Changelog

Recent updates and improvements to IntervalCoach.

Friday, June 5, 2026

  • New: Log time off straight from the calendar or training plan. The "+ Add" menu now has Sick, Injured and Holiday alongside Workout and Race — pick a date range and whether you're fully unavailable or just limited, and the coach eases off or pauses training for those days (with a gradual ramp back once you're past it). No more hopping to Intervals.icu to mark a sick week or a holiday. You can edit or remove an entry later from its detail view.
  • Improved: Date pickers across the app now share one consistent calendar, and every week starts on Monday.
  • Fixed: The Daily Briefing could show a mismatched card first thing in the morning — an old date and a previous day's workout at the top, with today's recovery numbers layered underneath. This happened when you opened it before that day's briefing had been built (for example when you wait for your watch's overnight data to sync). It now only ever shows the current day's briefing, and if it isn't ready yet it tells you it's waiting for this morning's data instead of showing stale information.
  • Fixed: If you have your daily briefing set to build after your morning HRV and sleep sync, it now reliably gets created (and your briefing email sent) once that data arrives, instead of occasionally not updating until later in the day.
  • New: A public Roadmap link in the top menu and footer, so you can see what we're working on now and what's coming next, and upvote the features you want most.

Thursday, June 4, 2026

  • Fixed: Upgrading your plan or buying a Coach+ top-up could fail at the payment step with a tax-related error. Checkout and top-ups now go through cleanly again.
  • Fixed: The Agent Log no longer shows a misleading "TSB 0 / CTL 0" on a wellness re-check that was skipped (for example when your wearable syncs outside the midday re-check window). Those rows never read your fitness, so they now just show that the check was skipped, without the alarming zeros. Your actual fitness numbers were never affected.
  • New: TrainNow can now build a workout to a target training load. Toggle "Target TSS" on the setup step, pick the TSS you want, and the coach sizes the session to hit it: it keeps the chosen workout type's natural intensity and sets the right duration. Prefer to set the time yourself? The "Duration" option works exactly as before.
  • New: Club events can now be edited, and any member can add one. Create a group ride or target race, then tweak its name, date, sport, priority or distance later instead of deleting and recreating it. You can edit or remove the events you created; club owners and admins can manage every event. Members who already added an event to their calendar keep their entry.
  • New: Club event notifications. When a club you're in adds a new event, you'll get a push so you can add it to your calendar. If an event you already added gets cancelled or moved to a new date, you'll hear about that too, so your plan stays in sync.
  • New: Discoverable clubs. Flip on "Discoverable" in your club's settings (or when you create it) and your club shows up in the new Discover section on the Clubs page, where anyone can join without an invite code. Making a club discoverable is a Pro/Max feature; joining a public club is open to everyone. Prefer to stay private? Leave it off and keep using invite codes as before.
  • Fixed: The plan label in the sidebar and account menu could still show "Pro" after a subscription had lapsed. It now reflects your current plan everywhere: Free, Trial, Pro or Max, with a one-tap Upgrade option (Pro or Max) on the free plan.

Wednesday, June 3, 2026

  • New: The Clubs area got a homepage-style refresh. The clubs overview now opens with at-a-glance stats (how many clubs you're in, total teammates, and how many you manage), and each club now leads with an Overview tab — your weekly digest, the top 3 on the leaderboard, your next event, and recent activity, each with a one-tap jump into the full section.
  • Improved: When the coach caps your intensity for the day (e.g. elevated resting heart rate, low blood oxygen, poor sleep), your workout's intervals are now actually eased to match — before, the cap showed up in the explanation but the interval targets weren't lowered. VO2max and anaerobic sessions instead keep their intensity and trim volume, so the hard stimulus stays intact rather than turning into a flat in-between effort. Running workouts now honour the cap too (they were previously left unscaled).
  • Fixed: A running interval labelled by distance (like "500m") could be misread as a duration in minutes — turning an 8×500m session into eight 500-minute intervals with a wildly inflated training load (700+ TSS). Distance-labelled run reps are now handled correctly, so the workout and its TSS come out as intended.
  • New: Training methodology — pick the Norwegian method in Settings → Training (all plans). "Norwegian Singles" turns your quality days into controlled sub-threshold work (the "golden zone" just below threshold) instead of all-out VO2max sessions — steady, repeatable intensity. "Norwegian Doubles" adds a second, shorter sub-threshold session on the days you've set up two training slots for (AM + PM) to build threshold volume with less strain — days with a single slot simply stay singles, never double-booked. There's also the "Easy Interval Method" — lots of easy aerobic work with frequent short, moderate intervals that never go truly hard. Recovery and taper weeks stay easy as always.
  • Improved: Your weekly plan now follows the workout-type preferences you've told the coach. If you favour certain types (say, more VO2max) and prefer to minimise others (like tempo or sweet spot), your planned intensity days now lean into the ones you want and steer clear of the ones you don't — the same preferences that already shaped on-demand workouts now also shape the week ahead. Recovery and taper weeks stay deliberately easy regardless, so the preference never adds intensity where it shouldn't.

Tuesday, June 2, 2026

  • New: Club leaderboards can now span different time windows. Pick a metric first, then choose 7D, 30D, 90D, or 1Y — so the volume boards (training load, distance, and time) can rank your club over the last week, month, quarter, or year instead of only the trailing 7 days. The fitness boards (CTL, CTL growth, badges) keep their own natural timeframe.
  • Improved: The Daily Briefing now only lists signals that actually need attention. Normal-range observations (recovery normal, sleep within range) were showing up labelled "Noted" and crowding the list — those are now hidden, so the Signals section shows what to watch or act on, and disappears entirely on a calm day.
  • Fixed: Your Daily Outlook no longer tells you to "adjust the intensity for recovery" when today's workout has already been swapped to an easier recovery session. When auto-adapt has already eased your session, the outlook now acknowledges that it's done instead of asking you to make a change that's already been made. (If your settings stage the swap for your approval instead, the outlook still suggests it, since the original is still on your calendar.)
  • New (advanced): A workout-duration mode in your Training Volume settings. The default is unchanged — "I set the duration", where workouts aim to fill the time you set each day. Switch to "Coach picks the duration" and that time becomes a ceiling instead: the coach picks the most effective (often shorter) duration within it, rather than padding a session to fill the slot.
  • Improved: When you set a training schedule that's well above what you've actually been training lately, the schedule editor now shows a gentle heads-up — IntervalCoach ramps you up gradually rather than matching the full amount from week one. Helps if you filled in your available time thinking of it as "when I'm free" rather than "how much I want to train".
  • New (beta): Your weekly plan can adjust itself when you change your calendar. Add, move, or delete a workout and the week rebalances around it — staying within about 10% of your weekly load target and keeping hard days well spaced (no two back-to-back), without ever touching today or sessions you've already done. Workouts you added yourself can be shifted or eased to fit; your own change always comes first. Flip on "Self-adjusting weekly plan" in Settings → Beta to try it.
  • Fixed: The mobile menu now includes the Decisions page, so you can see why the coach made each call from your phone — it was only reachable on desktop before. Coaches also get their Coach Mode link there.

Monday, June 1, 2026

  • Fixed: Toggling your cycling target (power ↔ HR) or running target (pace / HR / power / auto) in Settings now actually rewrites the upcoming workouts on your Intervals.icu calendar with the new target. Before, the setting was saved but already-scheduled workouts stayed on the old target indefinitely — you had to wait for the next daily-plan cron tick or manually delete and regenerate each one. Now the save kicks off a plan regeneration in the background, the same way changing your training demand or schedule already does, so the next time you look at your calendar the workouts have switched over.
  • Improved: The post-workout activity detail modal got an editorial redesign. The primary stats — duration, distance, and TSS — now sit as three values on a shared baseline, with TSS colour-coded by intensity (green / amber / red). Power metrics (avg / NP / max / IF / VI) collapse into a single 3-column grid instead of an awkward split, heart rate and speed/pace now share one row, and a new Conditions block groups elevation, cadence, and temperature together — cadence moved out from under Speed. The duplicate calories/work block at the bottom is gone (they're already shown in the energy pill at the top). The Post-Workout Analysis section now opens with a brand-coloured editorial mark, refined highlight chips with a dot accent, an amber callout for areas to improve, and the coach's closing note set as a pulled italic blockquote. The duplicate Notes section that echoed our own analysis dump from Intervals.icu is now hidden, and the Nutrition card lists meal examples as a vertical bulleted list instead of one long dot-separated sentence.
  • New (beta): Daily Briefing now on web. Tap your Daily Outlook on the dashboard to open the long-form briefing — full readiness reasoning, today's signals, today's workout with approve/reject for any pending swap, wellness + fitness snapshots, your last workout, and the coach note. Same view that's been in the iOS app. Flip on "Daily Briefing on web" in Settings → Beta to try it.
  • Improved: The "Est. Recovery" time in your post-workout analysis email is now grounded in your own recovery curve instead of a generic estimate. Once your personal recovery profile has a confident curve for a given workout type (Threshold, Tempo, VO2max, etc.), the recovery time is derived from how fast you actually clear that kind of session rather than a one-size-fits-all number. Until a curve is confident enough, it falls back to the previous estimate.
  • Fixed: The signal category headers in the Health detail popup (Recovery, Sleep, Load, Bio) now show in your own language instead of English. The signals underneath were already translated; only the group headers had been left untranslated.
  • New: Clubs — train with the people you ride and run with. Create or join a club to share an activity feed (who joined, badges earned, completed workouts), compare on fair leaderboards (weekly TSS, consistency, and 4-week fitness growth — not just raw watts), and post shared events that each member can add to their own calendar, where the coach folds them into their individual plan. You choose what you share per club, and your recovery and wellness data is never shared with clubmates. Joining a club is free; creating one is part of Pro (up to 10 members) or unlimited on Max.
  • New (Max): Weekly AI club digest — a short, group-focused summary of how your club trained that week (combined load, who is trending up, badges earned), written by the same coaching engine as your daily briefing and shown at the top of the club's Activity tab.
  • Fixed: When your goal event is set to automatic and your current event passes, your training plan now rebuilds toward your next goal on its own. Previously the goal would quietly roll over to the next event but the schedule wasn't recalculated, so the coming weeks sat empty until you manually re-picked a goal in Settings. Now the day after a goal event finishes, the plan regenerates automatically for whatever your next event is — with sessions back on your training days.
  • Fixed: The Sunday plan refresh no longer collapses a week down to a single session when the plan changes shape — for example the easier recovery week right after a big event. Days whose workouts had already been scheduled and then cleared were being treated as "already handled" and skipped, so the refresh could leave just one workout standing on an otherwise normal training week. The refresh now only skips days that still have a real workout on your calendar, and fills the rest of the week as intended.
  • Improved: New athletes no longer get a wall of false warnings before there's enough data to back them up. Load metrics like ramp rate and acute training load read alarmingly high when your fitness is still building off a handful of sessions, and HRV / resting-HR alerts need about two weeks of readings before they mean anything. Until each pillar has enough history, that section now shows a single calm "calibrating" note instead of red and amber alerts, then switches to full analysis once the data is there. Signals that don't depend on history — like your recovery score and sleep — keep working from day one.
  • Fixed: A short commute (or any unrelated short ride) no longer makes your planned session disappear from the Calendar. The calendar was hiding every planned workout for a day the moment any activity was logged — so a 30-minute bike commute could wipe your planned long Z2 ride, or even hide a planned run. The calendar now only hides a planned session once a completed activity actually matches it (same sport, with enough duration and intensity), the same way the dashboard already does. Your planned session stays visible until you genuinely do it.
  • Fixed: The post-workout analysis of a race you just finished now reads as a race recap, not a build-up session. If your activity matched a race on your calendar (A, B, or C), the analysis could describe it as prep that "will serve you for race day" — as if the race were still ahead — especially when you had another race coming up later. It now recognises that the activity is the race itself and writes about how you actually performed and recovered.
  • Fixed: Your weekly session count now includes the rides you plan yourself. If you set "5 sessions a week" and already have, say, a fixed weekend ride on your Intervals.icu calendar, the coach used to add 5 of its own workouts on top — 6 in total. It now counts your own planned ride as one of the five and generates four, so the total matches the number you asked for.
  • Fixed: Regenerating your plan, or changing settings, no longer leaves duplicate workouts on the same day. A background plan rebuild and the daily workout generator could run at the same moment and each add the same session, so you'd end up with two identical workouts on one day, and regenerating again only stacked more. The two now coordinate through a shared lock so only one writes to your calendar at a time. (Also hardened a couple of related edge cases in how stale workouts are cleaned up.)

Sunday, May 31, 2026

  • Fixed: A handful of unavailable days on your Intervals.icu calendar (a vaccination Wednesday, a weekend away, a 3-day work block) no longer flips the entire week into a near-empty "Holiday" recovery shape and wipes your already-pushed sessions when Sunday's plan regeneration runs. The week-classifier was escalating to a full Holiday week as soon as any single day was marked unavailable, which collapsed the dayPlan to a couple of token recovery sessions and let the post-regen cleanup pass remove every IntervalCoach-pushed workout that no longer matched the sparse plan. Hit hardest on peak and pre-race taper weeks: a Wednesday appointment 2 weeks out from an A-race quietly emptied the rest of the week. Now: up to 3 unavailable days are handled at the day level (each day blocked individually, like before), and the week keeps its natural Build / Peak / Taper shape and its planned sessions. Only when more than half the week (4+ days) is genuinely unavailable does it escalate to a proper Holiday week — which is when the periodization actually wants to treat it as recovery.
  • New: The race-event form now actually pre-fills the planned load from sport + target time. The help text has been promising "Load auto-calculates from distance + target time + sport" for a while, but the field was being left blank and the planner saw a 0-TSS race. The form now shows the estimate in the Load placeholder as you type (e.g. "~245 (auto)" for a 5-hour Ride) and backfills it on save if you leave the field empty, using a sport-aware Intensity-Factor band — short races stay close to threshold, ultras drop into long-aerobic territory. Set Load yourself to override, as before.
  • Improved: Race distance cap raised from 1000 km to 1600 km, and planned-load cap from 2000 TSS to 5000 TSS, so randonneuring brevets up to and including Paris-Brest-Paris (1200 km / ~90 hours / ~2700 TSS) can now be entered with the real numbers instead of being silently clipped.

Thursday, May 28, 2026

  • Fixed: The activity heatmap on Analytics and your profile no longer shows recent training days as rest days for athletes who had deleted and later re-created their IntervalCoach account. The heatmap reads from a cached training-history snapshot that was being left behind on account deletion instead of cleared — so a returning athlete picked up their old snapshot and any days trained while they were away never filled in. The snapshot is now removed on deletion (so a fresh signup always rebuilds clean), and existing affected accounts can be rebuilt from full Intervals.icu history.
  • Fixed: Training Milestones now unlock again after each workout. Achievements that are awarded per activity — Century Day (100+ TSS), Long Haul (3+ hour session), and the 7- and 30-day training streaks — had stopped being granted, so they stayed locked even once you'd clearly earned them. They now award reliably as your activities sync. Milestones you already earned but never received are filled in retroactively, so your card catches up to what you've actually done.

Wednesday, May 27, 2026

  • New: Pre-activation primers on harder cycling sessions. Sweet Spot, Threshold, VO2max, micro-intervals, anaerobic / sprint, and force / climb workouts now end their warmup with a short 2-3 minute primer — a brief specific preview of today's main-set intensity (or a low-cadence torque primer for force and climbing days), so the first real interval doesn't hit cold. The primer takes its power straight from the workout: a sweet-spot day primes at sweet spot, a threshold day primes at threshold, a VO2max day primes at VO2max. Total workout duration is preserved — the primer replaces the last 2-3 minutes of the smooth warmup ramp, so the main set keeps its full budget (and full rep count). Skips automatically on Recovery and Endurance days where the warmup ramp already eases you in, on Progressive workouts that build up across reps as their own opener, on Cadence drills that are themselves a neuromuscular warm-in, on Test protocols with their own structure, on Race-Simulation / Race-Pace / Openers workouts that are primer-style by design, and when the warmup is too short to host a primer without dropping the smooth ramp below 6 minutes (typically 60-min sessions of the longer-primer workouts).
  • Fixed: The daily email's week overview no longer mislabels empty calendar days as "Training" / "Trainings­dag". When the planner hasn't scheduled a workout for a given day — for example during a race-week taper, a recovery week, or any time the dayPlan legitimately leaves a slot blank — the email was filling the gap with a generic "Training" placeholder based on which days you'd enabled in Settings → Training Schedule. That made it look like a workout was planned when none was, which read as wrong on rest days bracketing an A-race. The fallback is gone: an empty calendar day now shows as rest, period. Days with a real planned event still show the event name as before.
  • Improved: The week-overview block on the daily email is now a rolling 7-day window — 2 days back + today + 4 days ahead — instead of locking to the current Monday-Sunday calendar week. At the boundary days (especially Sunday) the old framing barely showed any of the week ahead, which was the opposite of useful for a "what's next" section. The new window always shows you a couple of completed days for context plus enough lookahead to plan around. Section title updated alongside ("KOMENDE DAGEN" / "COMING UP" was misleading when half of what it showed was already in the past) — it now reads "OVERZICHT" / "AT A GLANCE", consistent with the existing weekly overview header.
  • Fixed: Analytics' HRV & Recovery chart now respects the Recovery Scale you picked in Settings. If you're on "1-6 (Polar)", recovery values render as Polar's native 1-6 ordinal with the bucket label ("3 / 6 (Compromised)") instead of the internally-mapped percentage ("40%"). The conversion to percentages was happening silently in the data pipeline — your Polar app would say "OK" but Analytics showed "55%", which felt inconsistent. Applies to the summary header and the tooltip on every bar in the trend chart.
  • Fixed: When you have two workouts scheduled on the same day (e.g. an AM Ride and a PM Strength session), the Dashboard now shows both. Previously only the first was rendered in the Today card and the second was silently dropped — the small "+1" badge on the calendar strip was the only hint a second workout existed. The Today card now keeps the primary session as the big card and adds compact "Also today" rows beneath it for any additional sessions, each tappable to open the workout structure. On the Training Plan page, generated workout rows are now clickable to view details — previously only race rows opened the details dialog, so on a day with two generated workouts you had no way to inspect either one.
  • New (beta): The dashboard Health popup now surfaces your recovery curve inline. Athletes who have flipped on "Recovery profile card" in Settings → Beta will see a compact "vs your own curve" status (on track / X% ahead / X% behind) plus a one-line half-life summary per stimulus, with a link out to the full chart on Analytics for deeper inspection. Previously the recovery profile lived only on the Analytics page, so the readiness verdict in the Health popup gave you no way to see how today's state related to your personal recovery shape without navigating away.
  • New: Brick days switch to a race-sim pattern in your Peak and Pre-Race Taper weeks. If your primary sport is multi (triathlon), brick days within ~3 weeks of your A-race now use a race-pace ride into a race-pace run instead of the default sweet-spot / Z2 pattern — so the final brick stimulus before race day actually rehearses how race intensity feels. Race Week stays out of this (openers only, no race-pace bricks 3-7 days out).
  • Fixed: The dashboard's 14-day readiness ribbon no longer renders as a ghost row of day-letters with nothing above them. The ribbon reads from Intervals.icu's readiness wellness field; for athletes without a source populating it (no Whoop, no Garmin Body Battery via the ICU integration, no Polar Nightly Recharge, no manual entry), every day was null and the bars collapsed to invisible stubs. The section is now hidden entirely when there's no data to show, so the Health card stays clean and the "today" wellness pills above keep doing their job. Connecting any source that writes to Intervals.icu's readiness field brings the ribbon back automatically.

Tuesday, May 26, 2026

  • Fixed: Running pace displays no longer round to "3:60 /km" — they now properly carry the seconds into the next minute and read "4:00 /km". The bug hit the running-form (loopvorm) card, the critical-speed history, and pace targets in the post-workout email. Same shape as the sleep-duration "7h 60m" fix from earlier this week.
  • Fixed: Library workouts that target a training zone (e.g. "60m Z2") are now uploaded with the zone reference intact instead of getting crushed to a literal 2% FTP main set. The DSL emitter was treating anything that wasn't marked as watts as "% FTP", so a Z2 zone reference from your Intervals.icu library ended up as a 60-minute, 4-watt soft-pedal on your calendar. Same fix covers HR and pace zone references on library workouts too. Reported by an athlete whose "LT1 1hr" library template was repeatedly showing up as a 4-watt ride.
  • Fixed: The Workout Structure chart on the event detail page no longer renders as a flat ~50% line for running and swimming workouts. The chart was only reading power targets and silently ignoring pace and HR targets, so any workout that used "% Pace" or "% HR" instead of "% FTP" fell through to a hardcoded 50% fallback. A 4×3min VO2max run with intervals at 105-120% pace looked identical to a recovery jog. The chart now reads pace and HR targets too, including the nested steps inside repeat blocks, so the work intervals show as proper spikes against the threshold line.
  • Fixed: Threshold workouts can no longer pile up absurd amounts of Z4 work in long slots. The phase-based ceiling on threshold work (30 min in Base, 40 in Build, 45 in Peak) was only enforced for two of the threshold templates — the rest could be looped to fit any duration, so a 6h Sunday tagged "threshold" was emitting 4×20=80 min of Z4 plus hours of endurance padding, well past the Coggan/Friel sustainable upper bound for a single session. Progressive Threshold, Reversed Progression, Threshold Repeats, Criss-Cross, Descending-Rest, and Threshold Surges now all honour the same phase cap, so the remainder of a long slot is filled with Z2 endurance instead of more threshold.
  • Fixed: Signing up or changing your training settings on a Sunday no longer leaves the rest of the current week empty. The planner was stripping the current week from the outlook whenever it ran on a Sunday, regardless of why it was running — fine for the Sunday-morning cron, broken for onboarding, settings changes, and manual rebuilds. Only the weekly cron now advances past the current week on Sunday; user-triggered regens always keep the current week so its remaining trainable days get filled.
  • Fixed: Run cooldowns no longer prescribe a pace that's faster than the main set. On recovery and easy runs the cooldown's first step was hard-coded to the top of the easy band (around 77% of threshold pace), which on a 55-65% recovery run came out faster than the work itself. The cooldown now caps its start at the main set's actual max intensity, so it always tapers down from where the work left off, never up. Affects recovery, active recovery, shakeout, drills, and any other run template whose main set sits below the default cooldown opener.
  • Improved: Trail Run is now a first-class race-event sport. Telling Coach+ you have a trail race (or picking the sport in the in-app race editor) creates the event with Intervals.icu type "TrailRun" instead of silently downgrading to "Run" — which keeps the elevation-aware pacing and trail-specific recovery profile intact for the rest of your plan. Coach+'s create/update tool descriptions now also hint when to pick TrailRun over Run.
  • New: TrainNow has a Trail Run sport option, separate from Road Run. Picking Trail Run shows the running workout catalog plus the Intervals.icu library workouts you've tagged as TrailRun (instead of mixing them with your road-Run library). The deeper trail handling — trail-aware prompts, GAP-normalised paces, trail-aware planning — ships in follow-up PRs.
  • Improved: Post-workout analysis on trail runs now reads like a trail-run analysis. The AI prompt now carries elevation gain, average vertical (m/km), distance category (sub-half / half-to-marathon / marathon-to-ultra / ultra), and a long-effort fueling cue for >2h sessions — so the analysis can talk about vert gained, downhill quad load, climbing efficiency, and ultra fueling instead of treating a 1200m-vert mountain run like a flat track session. Also fixes a related bug where TrailRun activities were being treated as generic "other" sport and missing the Running Profile block (Critical Speed, threshold pace, LTHR) entirely. Heuristic fallback flags mis-tagged trail runs (Run with ≥40m elevation per km) so athletes who forget to set the Intervals.icu sport tag still get trail-aware analysis.
  • Improved: Race pace plans for trail events now emit terrain-aware pacing. When the event is a trail race with elevation data on Intervals.icu, the pace-plan prompt receives total vert, distance, average vertical (m/km), terrain bucket (rolling / hilly / mountainous), and a power-hike threshold (~13% grade) — so the advice talks about distinct effort bands for climbs, flats, and descents instead of a single flat-equivalent pace. Applies to A/B race day pacing and C event tactical advice.
  • New: Five trail-specific workouts in the catalog — Long Climb (25-50 min sustained uphill threshold), Downhill Repeats (eccentric quad work for ultras), Power-Hike Intervals (steep walk-run rhythm), Technical Trail Intervals (VO2max effort over uneven footing), and Ultra Time-on-Feet (4-8h easy aerobic for ultra prep). Athletes with a trail goal now see these picked preferentially in their weekly plan instead of the road-running defaults. Hill Sprints, Hill Repeats, and Trail Long Run are also marked trail-specific so the same boost applies.
  • New: Brick is now a sport you can enable in your training schedule. Mark a day as Brick and the planner will schedule a bike-to-run pair on that day — sweet-spot ride into a short Z2 run during Build (or on any flagged intensity day), long Z2 ride into a steady Z2 run during Base / Peak / Recovery / Race Week. Both legs upload to your calendar back-to-back with a 3-minute T2 transition. Until now Brick was only available on-demand via TrainNow; the daily-cron and weekly-plan path is the follow-up the original launch promised.
  • Improved: Brick days adapt to rough readiness. When today's recovery signals cap intensity to Z2-or-below, or pull the daily TSS back by 30% or more, the brick collapses into a single easy ride instead of stacking the run on top — the second leg would compound fatigue you can't afford. The downgrade is surfaced in the coaching note so you can see why the plan changed.

Monday, May 25, 2026

  • Fixed: Your weekly plan no longer stays stuck in "Race Week" mode for weeks after a goal race finishes. A stale Race Week tag on the stored plan was being re-applied on every read — so every regeneration also stored a Race Week tag, looping forever. Athletes with a completed A-race and a distant next goal were getting only 2 recovery sessions per week as a result. The planner now requires an actual upcoming A or B race within the relevant window before it promotes the phase, so a completed race no longer echoes forward.
  • New (beta): Your own recovery profile, on the Analytics page. Pro and Max athletes can flip on "Recovery profile card" in Settings → Beta to see how quickly *you* personally bounce back from each kind of stimulus — tempo / sweet spot, threshold, VO2max, anaerobic, long endurance — instead of relying on a generic textbook recovery curve. We fit an exponential decay to your HRV, resting heart rate, and sleep deltas in the days after each hard session, then publish the half-life and a small chart per stimulus once there are enough sessions (6+) to trust the fit. Curves with thin data still show but render dashed so you can see them firming up over time. The underlying readiness check also starts nudging today's decision when you're behind your own curve — a new "behind recovery curve" signal fires when actual wellness is meaningfully worse than your published curves predicted, so the daily adaptation caps intensity even on a TSB that would otherwise read green. Profiles are warmed for every Pro/Max athlete every Sunday so the signal works whether or not you flip on the beta card.
  • Improved: The planner now respects your own recovery curves when deciding how to space hard sessions. If your published curve says you recover slower from threshold work than the typical athlete (e.g. half-life 5 days vs. the population default of 3), the planner will leave more days between threshold sessions. If your curve says faster, no change — the population default stays the floor (we never shrink it below the generic rule, just stretch when your data clearly says so). Only curves with stable confidence (≥40%) drive decisions; weak/provisional curves are ignored. Visible side effect: more breathing room between hard days for athletes with long recovery curves, and the workout-selection log lines call out "for your recovery curve" when a curve drove the decision so the source is auditable.
  • Fixed: Coaches no longer see two athlete switchers stacked on top of each other on the desktop sidebar. The dropdown at the top of the sidebar duplicated the "Athletes" list shown right below it — same names, same switching behaviour. The dropdown is removed; "Coach Overview" and switching back to your own training are still one click away via the Coach menu item and the coach-context indicator that appears when you're viewing another athlete. Mobile users are unaffected — the mobile menu (☰) still has its own switcher.
  • New (Max): Recovery profile now compares your own curves against your peer cohort. Max-tier athletes with at least one published curve see a "faster than X% of similar athletes" line on each bucket row in the Recovery profile card. Cohorts are segmented by sex and age bracket and require ≥10 athletes before the benchmark publishes (privacy + statistical floor) — small cohorts fall through to broader groups. Only the aggregate percentiles leave the cron; no per-athlete data is ever exposed in benchmarks. Beta gate still applies — flip "Recovery profile card" on in Settings → Beta and you need to be Max tier with at least one curve published.

Sunday, May 24, 2026

  • Improved: The daily workout your coach picks for you now actually references what it has learned about you. Notes the coach has accumulated over months — that VO2max sessions feel brutal in build, that you respond well to 2x20 sweet spot at 88%, that thresholds run hot the week after a poor sleep window — already shaped your weekly plan, but the daily workout selection and the coaching explanation in your email were blind to them. They're now threaded into the daily pipeline too, and ranked by semantic relevance to today's specific situation (today's workout type, today's recovery state) instead of dumped wholesale. The coaching explanation paragraph in your daily email reflects that — when you flagged VO2max as brutal last week, today's VO2max explanation will land with that context instead of generic prose.
  • Improved: The coach also writes new notes about you each day after the workout decision is made — a quiet write-step that asks "did anything happen today worth remembering for next time?" and only saves an entry when the answer is something genuinely actionable, not obvious from the structured plan. The notes are deduplicated weekly so the picture stays clean. Visible side effect: Settings → Coach Memories will gain a few entries per week instead of only growing when you give explicit RPE/feel feedback.
  • New: Added a Billat 15/15 VO2max workout to the catalog — 15s at vVO2max followed by 15s of easy float, repeated in 12-minute sets. This is the classic short-interval protocol from the original Billat paper and fills a gap: until now the shortest VO2max format on the bike was 30/30, with nothing for athletes who respond better to even shorter work bouts at true vVO2max pace. Available for both running and cycling, sits in the Build and Peak phases.
  • Fixed: Coach Mode athlete picker now actually appears on the phone — properly this time. Yesterday's "fix" mounted the switcher in the desktop sidebar, but the sidebar is hidden on mobile so coaches on a phone still couldn't switch context. The picker is now also in the More menu (the bottom-bar ☰ button), and the sheet auto-closes when you pick someone so you land straight on that athlete's view.
  • Fixed: Workouts pulled from your Intervals.icu library no longer end up with impossible power targets. The adapter was treating every power value as %FTP regardless of the original units — so a library workout written in absolute watts (e.g. "245W" for a threshold rep) became "245% FTP" on upload, which Intervals.icu accepts literally and renders as a ~600W interval on a 250W FTP. Ramp warmups and cooldowns (e.g. "ramp 45-75%") were also being mangled because the formatter only understood steady targets, not start/end ramps — they showed up as "15m undefined%" lines and lost their power info on the round-trip. The adapter now respects absolute-watt prescriptions, emits proper ramp ranges, and a new safety check rejects any rewrite that produces a target above 200% FTP so a broken workout never reaches your calendar — the planner falls back to a catalog template instead.
  • Fixed: The daily email greeting now matches the time of day it actually lands in your inbox. Before, the greeting was hardcoded to say "happy {day} morning" — so an athlete on Istanbul time who got their daily send at 21:41 (because the morning slot was missed and the fallback fired later) still saw "happy Tuesday morning." The greeting now picks between morning / afternoon / evening based on the local hour in your timezone, so a late-evening fallback send greets you with "happy Tuesday evening" instead. Translated across all 12 supported languages.

Saturday, May 23, 2026

  • New: Analytics page now has a Day / Week / Month resolution selector next to the time range. Previously the wellness charts auto-picked daily or weekly bars based on the selected range; now you can override that and pull TSS, HRV, HRV stability, and resting heart rate into the granularity you want — including a monthly view on the 90-day and 1-year ranges. Combinations that don't make sense (e.g. month bars over a 7-day window) are disabled to keep the chart readable.
  • Fixed: The Dashboard's "This Week — Load" card no longer double-counts today's workout. Once you completed today's planned ride it was being counted both in DONE (via the recorded activity) and in REMAINING (the planned event was still on the calendar), so FORECAST inflated to DONE + the same workout again — e.g. 391 done + 200 "remaining" = 591 forecast against a 257 target, even though the 200 had already happened. Completed activities are now pair-matched to scheduled events by date and sport, so a planned workout that's already been done is excluded from REMAINING. Brick days still show the unfinished leg as remaining when only one of two planned workouts has been completed.
  • Fixed: Sleep duration on the dashboard no longer reads "7h 60m" when you slept ~8 hours. The hour and minute portions were rounded independently, so when the fractional minutes rounded up to 60 the hour wasn't carried over — a night of 7h 59.7m rendered as "7h 60m" instead of "8h 00m". Same fix applied to the iOS dashboard tile and the Daily Briefing snapshot.
  • Fixed: Coach Mode athlete picker is now reachable from the sidebar on desktop, alongside the icon at every width. (See 2026-05-24 entry for the mobile follow-up — yesterday's change only covered desktop.)
  • Fixed: Recovery and Deload weeks no longer get systematically over-budgeted. Yesterday's Taper fix routed Taper / Race Week / Pre-Race Taper around the "skip enforcement when target is below 150 TSS" safety valve, but the same safety valve was still catching Recovery and Deload weeks — for athletes with CTL in the 15-25 range a recovery week routinely targets 100-140 TSS, and the per-session category floor compounded to ~1.7x that (e.g. target 135 → planned 226). Recovery and Deload are now also pinned to the contracted weekly total, the same way Taper weeks were yesterday.

Friday, May 22, 2026

  • Fixed: A C-race on your calendar tomorrow now triggers the same evening-before fuel-and-sleep push you already get when a hard workout is on for tomorrow. Previously C-races got no pre-event reminder at all — the existing nudges only matched A/B races or IntervalCoach-generated workouts, so a C-race fell between them.
  • Fixed: Weekly plans for athletes who train at an easy intensity (lots of Z2 rides) no longer overshoot the achievable TSS budget. The plan projection used a fixed 60 TSS/hr default when ramping toward the post-ramp ceiling, while the stored "what this athlete can actually do" cap on the same plan used the athlete's historical TSS/hr. For someone whose actual rides average 30-40 TSS/hr, the two numbers disagreed and the projection was happy to plan double the realistic weekly TSS — Build weeks could be planned at 1140 TSS against an availability ceiling of 578. The projection now uses the same TSS/hr figure as the cap, so a 20-hour-per-week Z2 athlete gets a Build target that fits their actual training intensity instead of an inflated number based on theoretical sustained-FTP riding.
  • Fixed: Taper weeks no longer get systematically over-budgeted. A safety valve in the per-day TSS distribution skipped the final "scale everything down to fit the weekly target" step whenever the target was under 150 TSS — originally added so new athletes with stale low CTL × 7 targets weren't starved by an artificially low budget. But legitimate Taper weeks (especially for athletes with CTL in the 15-30 range) routinely target 80-130 TSS, and the per-session category floor compounded to 1.5-2x the taper target. A user with a target of 129 TSS would consistently see plans of 226 TSS scheduled — defeating the purpose of the taper. The "skip when small" exemption now bypasses Taper / Race Week / Pre-Race Taper, so a small taper target is enforced exactly the way a coach would: trim every session proportionally until the weekly total hits the contracted number.
  • Fixed: FTP / ramp / run TT / swim CSS tests are now actually being scheduled into your weekly plan again. The scheduler had a "today's recovery must be green" gate that decided at plan-generation time whether to inject a test into Saturday's slot — but for athletes without Whoop, today's recovery defaults to a yellow signal as soon as any wellness signal nudges the intensity modifier below 1.0 (a single short night of sleep was enough). Saturday's recovery has nothing to do with Monday's recovery, so the gate was the wrong shape: it meant a non-Whoop athlete who was overdue for a test would just keep being overdue, week after week, because the test was never planned. The recovery check is now deferred to the day the test is actually scheduled — the daily adaptation pipeline already moves or swaps a test if you wake up red/yellow on test day. Other plan-time gates (training phase, week type, time since last test, TSB window for medium-priority scheduling, proximity to goal) are unchanged, so an overdue test still won't be planned during a recovery / taper / race week or within 2 weeks of your goal.
  • New: Dashboard's "Plan Goal" card now shows your projected fitness and projected form on race day right at the top, alongside a countdown ring, the race date (with multi-day support — "Fri, May 29 – Sat, May 30" for stage races), and your current training phase. The previous race card showed only the countdown and phase; the new version turns it into a one-glance answer to "am I going to be where I need to be on race day?". Phase transitions still surface ("Current mix: 70% Build, 30% Peak") so you see when you're crossing from one block to the next.
  • New: Dashboard now has a "This Week — Load" card showing your weekly TSS split into Done / Remaining / Forecast / Target. A two-row progress bar shows the target line above a live forecast bar (solid where you've completed work, dashed where it's still scheduled), so you can see at a glance whether the week ahead lines up with your target.
  • New: Your Health card on the dashboard now grows a 14-day readiness ribbon at the bottom — a green / amber / red pill for each of the last 14 days using the same recovery thresholds we use elsewhere, plus a count summary ("8 ready · 6 caution"). One card now shows both today's wellness signals and the two-week trend instead of two separate cards on the same theme.
  • Improved: Dashboard layout reshuffled so today's plan and the new weekly-load tracker sit in the top band, the upcoming-7-days calendar gets full horizontal width below them, and the wellness side panel trimmed from five stacked cards to two. Less scrolling, related cards live next to each other.
  • Fixed: Running VO2max sessions now use a true 1:1 work-to-recovery ratio with easy-jog recovery, instead of 3min hard / 2min "recovery" at a pace that was still in the Z2 endurance band. Previously, a 3min VO2max interval was followed by only 2min of recovery at the boundary of Z1/Z2 (about 65% threshold pace), which didn't let your heart rate drop enough between reps and blunted the VO2max stimulus. New behaviour: 3min hard followed by 3min of easy jogging at about 60% threshold pace (Daniels' E-pace), and the generic Z2 padding that was sometimes interleaved between intervals no longer applies to VO2max sessions — the recovery stays clean.
  • Fixed: Cycling threshold workouts no longer prescribe 3x20min at Z4 (60 minutes of threshold work in one session). Coaching literature (Coggan, Allen, Friel) treats 40-45min total at Z4 as the sustainable upper bound for a single threshold session; 60min belongs in specialist time-trial prep, not standard build or peak weeks. The total-Z4 ceiling per session is now 45min in peak phase (was 60) and 40min in build phase (was 45), so the generator picks 2x20 or 3x15 in peak and 4x10 or 3x12 in build, never 3x20.

Thursday, May 21, 2026

  • New: Settings → Training now has a "Default workout start time" card with one row per sport (Cycling, Running, Swimming, Other). Each row reads and writes directly to your Intervals.icu sport settings — set a time here and the AI uploads that sport's workouts at that hour instead of the legacy 09:00, and the value also shows up at intervals.icu so other tools that read your calendar (Hexis, Zwift, MyWhoosh, etc.) see the same time. Pulls fresh from Intervals.icu via a refresh button if you've edited the values upstream. Fixes the case where downstream tools kept overwriting your manually-edited start times because every IC upload was pinned to 09:00.
  • New: Settings → Integrations now has a card for your Intervals.icu workout library. Flip the whole library off in one click if you don't want the AI picking from it, or pick exactly which folders contribute on a per-folder basis. Folders you own are on by default; folders shared with you from other athletes or commercial workout packs (HNP, etc.) are off by default — flip them on if you specifically want those workouts in the pool. A synthetic "Workouts not in any folder" row covers anything sitting in your library root. The setting affects every AI selection path (your daily workout, weekly plan, the catalog the picker shows in TrainNow); manual browsing of the full Intervals.icu library is untouched.
  • Fixed: When you schedule a multi-week vacation on your Intervals.icu calendar, the "Pre-Holiday Push" label now only appears on the actual week before your vacation — not on the vacation weeks themselves. Previously, a 2-week holiday could show up as "Pre-Holiday Push" on both the week before AND the first vacation week (with the vacation overlay shown on top), because the label logic only checked whether next week was a holiday and forgot to also check whether the current week was already a holiday.

Wednesday, May 20, 2026

  • Improved: Coach+'s memory of you got noticeably sharper. New notes you give Coach+ — preferences, constraints, injuries, recurring patterns — now carry context tags so each note only surfaces in the situation it applies to: which sport (cycling / running / swimming), which intensity bucket (easy / tempo / threshold / VO2 / sprint), specific days of the week, indoor vs outdoor, and an optional expiry date for temporary states. "No intensity on weekends" only kicks in when planning Sat/Sun; "knee twinges on hill repeats" only surfaces when scheduling threshold-or-harder running, not on Z2 spins. When you chat with Coach+, the notes it pulls into context are now also picked by what your question is *about* — ask about today's threshold workout and it grounds the answer in your threshold-related notes, not your unrelated swim preference. Settings → Coach Memories now shows each note's tags as small badges, plus how many times Coach+ has heard you confirm it, so you can see at a glance what the coach actually believes about you and which notes have been validated multiple times. A weekly cleanup also merges near-duplicate memories that accumulate over months of chat ("I prefer mornings" said three different ways) into one canonical entry so the picture stays clean.
  • Improved: The post-event "what's next?" email now lands the evening of your race day (around 20:00 local time) instead of the next morning. Catches you while you're still in the post-event buzz and actively thinking about training, rather than after a night's sleep when momentum has cooled. If the evening slot is missed for any reason, it still falls back to a next-morning send — and the per-event dedup means you won't get two.
  • Improved: When the Dashboard or Training Plan shows the "no goal event set" state, the action button now opens the in-app goal wizard directly instead of routing to Settings. One tap to pick your next A or B race, instead of three.

Tuesday, May 19, 2026

  • Improved: The HRV, resting-heart-rate, and sleep baseline signals on your dashboard now compare today's reading against both your recent 7-day baseline AND your full 30-day baseline, and surface whichever picture is worse. Before, only the 30-day comparison drove the signal — so when your 7-day average had drifted down with a tough week, a fresh dip on top still flagged correctly against the 30-day mean, but a single off-day after a particularly strong week could read as "normal" against the long-term mean even though it was clearly below your recent normal. The dashboard now catches both cases in both directions — and symmetrically on the good side, a great day on top of a great week reads as solidly good rather than spuriously exceptional. Falls back to the 30-day-only comparison when you haven't logged enough recent data for the 7-day window to be trustworthy.
  • Fixed: Recovery weeks no longer pile up four consecutive 33-TSS recovery rides on the weekdays between weekend intensity sessions. The dayPlan was correctly allocating each weekday as an "endurance" stimulus (60-90 TSS at Z2 pace) — but the rolling workout-type selector then gave recovery-intensity workouts a deload-week boost equal to the endurance boost, and tie-breakers tipped the pick to "Recovery" on weekday after weekday. The end of the chain (`generateSingleWorkout`) caps a recovery workout's TSS at recovery rate × duration × 1.3, so a 120-min slot landed at ~33 TSS instead of the planned ~65. Reported by a Pro user whose Recovery week scheduled Sweet Spot on Monday, Sprints on Sat/Sun (the three intensity days) and four identical 33-TSS recovery rides Tue→Fri — totalling 384 TSS against a 451 weekly target. The deload boost now defers to the dayPlan's per-category allocation: when the day is planned as endurance/tempo/sweetspot, recovery-intensity workouts no longer get the deload boost, so the selector picks an endurance workout instead and the day delivers the TSS the plan budgeted for.
  • Fixed: When you ask Coach+ to "make this a recovery week", the change now actually lands instead of disappearing into five turns of empty prose. Reported flow: athlete asked to apply a recovery week, the AI repeatedly replied "ich starte jetzt die Neuberechnung, gib dem System einen Moment Zeit (1-2 Minuten)" across multiple turns — but the underlying tool call (`updateTrainingSettings({ mesocycleWeek: 4 })`) was being short-circuited by an "empty changes" guard that fired before the mesocycle-week branch could run, so the tool returned "No settings to update" and nothing changed. The guard now correctly recognises a mesocycle-week-only call as a real change and routes it through the dedicated periodization-preference write path. The system prompt was also tightened: whenever any Coach+ tool returns `success: false` or a rate-limit / validation error, the next reply must surface that error verbatim instead of continuing the prose as if it had succeeded — so "Plan regeneration limit reached (3 per day). 0 remaining." now produces "the plan-regeneration limit is already used up — try again after midnight, or I can adjust just today's workout instead" instead of an indefinite "wait a moment for the system to catch up".
  • Fixed: When you ask Coach+ to adjust today's workout, it no longer claims the change is done before the approval card has appeared. The reported pattern: athlete asked to lower today's workout intensity by 15%, Coach+ replied "I'm applying the 15% reduction now" three times across three turns before the Adjust Workout Intensity approval card finally showed up at the bottom of the chat. Reading past or present-progressive prose ("I'm applying" / "I've adjusted" / "I am executing") as a completed action, the athlete reasonably concludes the coach is broken when nothing actually changes. Approval-gated mutation tools (adjust intensity, generate workout, move workout, delete event, manage blackouts, update settings, create race) are now explicitly framed as queued for approval — Coach+ says "I've prepared a 15% reduction for today's Threshold Progression — please approve the card below to apply it" and only switches to past tense after the approval lands and the tool result confirms success.
  • Fixed: When Coach+ replaces today's workout while a TSS reduction is active (e.g. swap an HR-based ride to its power-based equivalent for the indoor trainer while a 0.8 readiness multiplier applies), it no longer adds a second reduction in prose. The reduced TSS target Coach+ passes to the workout generator is already encoded in the new workout — the intensity is dialled back, the interval count stays intact. But the AI was also telling the athlete in chat to "do only 4 of 7 intervals to respect the ratio", double-applying the multiplier the athlete had already accepted. The system prompt now spells out that the reduction lives in the workout structure, and Coach+ must describe the workout exactly as the tool produced it ("here's an 81 TSS version — same 7 intervals, intensity scaled to respect the 0.8 ratio").
  • Fixed: When you ask Coach+ to keep a generated workout HR-based (or power-based / pace-based), the override now actually reaches the workout generator. The chat tool accepted the "HR-based" flag from the AI but silently dropped it on the floor before calling the workout pipeline, so splitting a long endurance ride into a morning and afternoon half — with explicit "keep it HR-based" instructions — produced two power-based workouts anyway. The flag is now threaded through as a per-call override that takes precedence over your stored Settings preference for just that one workout (both halves, in the split case), without changing your default for future generations.
  • Fixed: The VO2max value shown in the Signals panel is now correct for athletes whose primary device is Garmin / Wahoo / Polar. Garmin computes VO2max from your cycling or running data using power+HR, but it doesn't write that value into Apple Health — only Apple's own walking-derived "Cardio Fitness" lands there, which is structurally lower than your real aerobic capacity. The signal pipeline was reading from Apple Health first, so a Garmin athlete with an actual 53 ml/kg/min reading saw it pinned around 42-43 in the app, and the trend detector was effectively tracking iPhone walking rather than cycling fitness. The pipeline now prefers Intervals.icu's VO2max (where Garmin / Wahoo / Polar / Strava write directly) and falls back to Apple Health only when no device-direct value is available, so Apple Watch users are unaffected.
  • Fixed: The fitness chart's CTL projection no longer flatlines or dips during weeks loaded with race events. After the earlier fix to stop the race's own TSS from smearing across all 7 days of its week (which had been inflating CTL in the run-up to a goal), the race load was being subtracted from the week's training budget but never added back on the actual race day — so a 600-800 TSS brevet contributed zero to projected CTL. Five back-to-back C-race brevets in May could project CTL to fall from ~45 to ~36 instead of the build the plan was actually calling for. The projection now carries the per-day race events through and applies each race's load as a single-day spike on its actual date, so a brevet block shows up as the rising staircase your training plan actually produces.
  • Fixed: A 1-day SICK marker on your Intervals.icu calendar (think one bad evening of food poisoning) no longer triggers three weeks of scaled-down training. The post-illness ramp-back was sport-agnostic on duration — a single-day marker and a 14-day flu both produced the same 3-week 55% / 75% / 88% ramp, so one bad meal cost the athlete a "Return from Illness" week followed by two "Post-Illness Build" weeks. The ramp now scales with how long the marker actually spanned: ≤2 days gets no ramp at all, 3-7 days gets a single Return-from-Illness week at 75%, 8-14 days gets a 2-week ramp at 75% then 88%, and only >14-day illnesses get the full 3-week 55/75/88 ramp. INJURED markers always use the full 3-week ramp regardless of duration — injuries warrant a more cautious return than illness. The check still respects an active SICK/INJURED in the current week (still recovering, no ramp logic applied).
  • Fixed: Asking Coach+ to "change next week's plan" on a Friday or Saturday now targets the actual upcoming Mon-Sun, not a rolling 7-day window starting tomorrow. The chat agent's date reference only listed the next 7 days as Today → Today+6, so on Friday May 8 the visible range stopped at Thursday May 14 and the AI applied "next week" changes to Sat-Thu (today+1 through today+7) instead of the real ISO next week (Mon May 11 - Sun May 17). The prompt now includes explicit Mon-Sun anchors for both this week and next week, and an instruction to use the Next-week range whenever the athlete says "next week" or "the following week".

Monday, May 18, 2026

  • New: IntervalCoach is now a native Mac app on the Mac App Store. Same features as on iPhone and iPad, reshaped for the desktop — sidebar navigation instead of a bottom tab bar, a native Settings window (⌘,), ⌘1-⌘5 to jump between Dashboard, Train Now, Coach+, Calendar, and More, and multi-window support so you can keep the calendar open next to the dashboard. macOS 14 Sonoma or later. If you already use the iPhone or iPad version, your session carries over. Download from the [Mac App Store](https://apps.apple.com/us/app/intervalcoach-ai-training/id6760976369).
  • Fixed: Post-workout analysis no longer dings you for a "shorter final Z1 block" or "brief rest lap" caused by a few seconds of recording dead-time at the end of your activity. When your head unit keeps logging for 1-30 seconds after you stop pedaling, Intervals.icu sometimes detects that sliver as its own micro-interval (e.g. 23s at 9W, or 1s at 0W) — and the analysis AI was reading those slivers as planned-but-mis-executed structure and silently shaving compliance off your score. The analysis input now filters out trailing sub-30s near-zero-power slivers before the AI sees them, and drops any sub-15s low-effort sliver anywhere in the activity. Real short sprints (e.g. a 10s neuromuscular effort at 800W) and legitimate Z1 cooldown reps at real recovery power survive the filter unchanged.
  • Fixed: The weekly summary email no longer reports "Week N summary — 0 TSS, 0 sessions, 0 hours" when the Sunday-evening cron run gets delayed past your local midnight. The cron fires hourly on Sunday and Monday UTC, and if the per-athlete handler ran with your local clock already in Monday — e.g. a Berlin athlete getting their email at 04:47 Monday morning after a queue backlog — the "completed week" lookup picked the brand-new (empty) Monday-Sunday week instead of the one that actually just ended. The lookup now distinguishes Monday-local from Sunday-local and returns the just-completed prior week in both cases, so the email shows the right week number and real stats regardless of whether the handler landed Sunday evening or Monday morning.
  • Fixed: The Daily Outlook on the dashboard no longer keeps telling you to "prioritize recovery today and focus on a light recovery session" after you've already finished your workout for the day. The Outlook is generated once per local day and cached, so a morning verdict (when you hadn't trained yet) survived for the rest of the day even after a ride landed on your calendar with a ✓ Completed badge — the workout card below the Outlook showed the right state, but the Outlook copy didn't budge. A deterministic check now runs at read time: when the cached Outlook recommends a recovery session AND you've already completed a workout AND no other session is still scheduled, the cache is dropped and a fresh Outlook is generated that acknowledges the completed effort instead of prescribing more training. The prompt was also tightened so the freshly-generated copy frames the day as "recovery from today's session" rather than "do a light recovery session today" when there's no remaining work to do.
  • Fixed: When your week mixes cycling with cross-training, the daily cron no longer silently drops the bike session on the cross-training day. If you have a Strength workout on the calendar (imported from Apple Health, a coach-set Intervals.icu plan, or anything else not generated by IntervalCoach) and your IntervalCoach plan also schedules a Ride on the same day, the Ride was disappearing — the Training Plan page correctly showed both sessions, but only the Strength one landed on the calendar. Root cause: the daily cron's adaptation step skipped the day whenever it saw any non-IC workout (sport-agnostic), and the rolling catch-up that fills gaps only scanned tomorrow → day+7, so today's missing Ride was invisible to both paths. The catch-up scan now starts at today and uses the sport-aware check that was already in place for future days — your Strength is recognised as coverage for the Strength slot, and only the missing Ride gets generated.
  • Fixed: Regenerating your plan no longer wipes today's workout off the calendar with nothing to replace it. After a plan regenerate (manual rebuild, or any of the auto-triggers like changing your goal or training schedule) the regeneration pipeline deletes every IntervalCoach-authored workout in a 28-day window starting from today, then rebuilds the rolling horizon for day+1 → day+7 — today was getting deleted and never regenerated. The daily cron normally fills in today's session, but once it has already run successfully for the day it self-gates as "Already ran today" and refuses to do it a second time, so postponing your preferred email time or hitting regenerate again couldn't recover the workout — today was gone for the rest of your local day, with tomorrow's cron tick the earliest fix. The regeneration path now explicitly includes today in the rolling fill so a fresh structured workout lands on your calendar immediately after the delete. The daily cron and onboarding paths keep the existing day+1 → day+7 horizon — only the regenerate path opts into regenerating today, which preserves the cron's duplicate-email guard.
  • Fixed: Regenerating your plan while a Peak week is reclassified into a Race Week (or any time a week's session count shrinks) now actually clears the old workouts off your Intervals.icu calendar. Reported by macaroni518 on the Intervals.icu forum after the deterministic D-7 → D-0 race-week protocol shipped: the training plan correctly said "Race Week, 1 session" but his calendar still showed four stale Peak-classification sessions — Aerobic Endurance, VO2max, Aerobic Build, Aerobic Endurance — all tagged [Weekly Plan - Taper] in the description. Root cause: a cleanup step added back in INT-884 was placed in the regeneration pipeline before the new day plan had been computed, so its "is there a day plan to reconcile against?" guard was always false and the cleanup silently did nothing on every regen since. The reconciliation now runs after the day plan is final — for every IntervalCoach-prefixed workout on your calendar in the regenerated horizon, we delete the ones whose (date, sport) slot is no longer in the plan. User-created workouts and non-IC events are still never touched. The post-regen activity log now records the count of deleted workouts so future debugging can see at a glance whether this step ran.
  • Fixed: Daily Outlook no longer tells you to take a recovery day when the workout on your calendar is unchanged. Reported four times now — most recently by n0rt0nthec4t on the Intervals.icu forum after the latest fix shipped: the Outlook said "your scheduled Aerobic Endurance workout should be significantly modified" and showed a red "Recovery" pill, while the actual session on the calendar was still the original 54 TSS endurance ride. The same pattern hit Marco Baiocco twice; earlier rounds added grounding fixes that helped most cases, but a "go" readiness decision with two advisory signals (SpO2 below normal + a multi-day training streak) still slipped through because the prompt only locked down "modify" decisions, not "go" decisions where the AI then independently decided to override the calendar. Two changes ship together: the readiness prompt context now also locks down the "go + advisory signals + no actual adaptation" case with the same anti-fabrication rules and explicitly forbids the AI from picking rest or recovery as the recommendation when a real workout is scheduled and unchanged; and a deterministic write-time invariant check now drops the AI assessment entirely when it produces a rest / recovery verdict on a day where a normal workout is scheduled and unmodified, so the Daily Outlook card hides itself rather than rendering contradictory advice next to the workout you're actually about to do. Scheduled rest days, real adaptations, and race days are all exempt — those legitimately can carry a rest verdict.
  • Fixed: Dashboard "Goal Progress" card no longer hides your A-race when you also have a training-goal template active. If you picked a goal template during onboarding (e.g. "FTP / Threshold" or "Speed / Power Block") and separately had an A-race tagged in your Intervals.icu calendar, the template silently overrode the race — the dashboard would show the 12-week template horizon and your real A-race vanished from the Goal Progress card, leaving the countdown pointing at the wrong date. The card now picks whichever goal you set most recently: if you tagged the A-race in your calendar after picking the template, the race wins, and vice versa. Existing affected athletes get the right card automatically on next dashboard load — no settings to change. Reported by Allan Robinson.
  • Removed: The Training Plan page no longer surfaces a separate Warnings panel at the bottom. Load and recovery signals (HRV suppressed, sympathetic dominance, volume spikes, sleep deficits, etc.) already drive the Dashboard and the Health sheet — duplicating them on the Training Plan page produced inconsistent readings (different deviation windows between the two surfaces) and on iOS rendered raw translation keys. The signals engine is unchanged; the Dashboard remains the canonical place to see current readiness flags.
  • Fixed: Training Plan focus column now correctly shows "Endurance" for endurance-focused weeks instead of the literal key "TrainingPlan.Focus.Endurance". The translation was missing from the focus namespace — added across all 12 supported languages.
  • Fixed: Athletes returning from a SICK event no longer get a "Holiday" week with no scheduled workouts. The off-by-one on exclusive end-dates lets a sick period that ends Monday morning leak into the following Monday and flag the new week as a holiday, on top of being a return-from-illness week. The periodization priority chain previously made Holiday win, which produced a recovery-leaning TSS target but no daily workouts. Return-from-illness now takes priority and the planner generates a real 55%-load week instead of an empty placeholder, so users like Sender (who lost three regenerations to the empty-plan loop) get a usable plan back as soon as the cron next fires.
  • Fixed: The Intervals.icu workout library picker now includes workouts from libraries shared with you (e.g. HNP - The Complete Workout Library and similar public/subscribed collections), not just folders you own. The Intervals.icu /workouts endpoint only returns workouts in your own library and silently omits subscribed ones; we now also walk the /folders endpoint and union in workouts from folders whose owner is not you. Same 24h cache as before, just with the full set of workouts in it. Reported by a Pro user whose 123-workout HNP library wasn't showing up in the picker.

Sunday, May 17, 2026

  • Improved: Analytics charts (HRV & Recovery, HRV Stability, Resting Heart Rate) now switch to a day-by-day view when you select the 7D or 30D time range. At 7D the old weekly aggregation showed exactly one bar — not useful. The 90D and 1Y ranges keep the weekly view since daily values at that scale are too noisy. HRV Stability specifically uses a rolling 7-day window at daily granularity so the "stability over time" reading stays interpretable.
  • Fixed: The Blood Oxygen card on the Health sheet no longer claims things like "SpO2 95% is below 95%". The detail line was rounding the SpO2 reading before displaying it, so a real-world 94.7% reading rounded UP to 95% in the message while still flagging as below the 95% threshold — visually contradictory. SpO2 is now shown with one decimal (94.7%) across the critical, low, and below-baseline signals so the value the user sees matches the comparison.
  • Fixed: The HRV Stability and Resting Heart Rate charts on the Analytics page now show data for athletes with Whoop connected and an iPhone pushing HealthKit. Previously the server dropped every HRV/RHR/sleep/SpO2/respiration value from the iOS HealthKit sync as soon as Whoop was connected, assuming the Whoop→Intervals.icu mirror would fill the gap — but that mirror fails silently for users whose Intervals.icu OAuth lacks the wellness write scope, so the dropped HealthKit data was the only realistic fallback. Now HealthKit data flows through to Intervals.icu as well; on the rare day Whoop and HealthKit disagree on a shared field, the Whoop reading is preserved (HealthKit only fills the gaps).
  • Fixed: Enabling Walking or Hiking as a training day in Settings → Training Schedule no longer fails with "must be an array of valid sports (Ride, Run, Swim, Strength)". The save-settings endpoint had a stale validation list from before Walk and Hike shipped — it would silently reject any save that included a Walk or Hike chip on a day. The validation across settings, generate, upload, and event-creation routes now reads from a single shared SPORTS constant, so this kind of drift can't recur the next time we add a sport.
  • Fixed: Walking and hiking workouts now show the correct icon everywhere. A walk on the Training Plan page rendered with a cycling icon; on the calendar event detail it fell back to the generic activity pulse. Both surfaces were each maintaining their own sport-to-icon switch and never got the Walk + Hike cases added. The mapping now lives in a single shared SportIcon component used by the training plan, the calendar grid, the calendar event detail dialog, the dashboard upcoming card, the dashboard today panel, and the day-events sheet — same mapping everywhere, no more drift.
  • New blog post: "What to Train For When You're Not Racing" — a guide to the nine non-race goal templates (General Fitness, Return to Sport, Off-Season Base, Weight Management, Speed/Power Block, FTP/Threshold, Getting Started, Maintenance, Long Walk/Multi-day Hike) and how to pick between them.
  • Fixed: Walk and Hike TSS is now whatever Intervals.icu computed from your HR — we no longer apply a per-hour floor on top. The original idea was to give walks/hikes some credit when Apple Health and Strava strip the HR/power streams (so a 90-min walk wouldn't show as 0 TSS), but the floor was symmetric: it also overwrote real, low-intensity walks where HR data was present. A genuine Z1 recovery walk that scored 8 TSS from HR was getting bumped to 15. From now on, if the streams are stripped, the walk shows 0 TSS; if they're present, it shows the real hrTSS — no inflation either way. The planned-walk estimate in TrainNow still uses 15 TSS/hour as a forecast (we have no HR data before the walk happens), but the *recorded* value reflects reality.
  • Fixed: Missed-workout push nudges actually fire now. The proactive coaching nudges that ship at 14:00 local time (Pro/Max) come in two flavours — a race countdown 1-3 days before an A/B race, and a "you skipped yesterday's workout" prompt that opens Coach+ pre-filled with a reschedule question. The missed-workout half has been silently broken since launch six weeks ago: it looked up yesterday's planned workout in the in-memory day plan, but that data structure is cleared as soon as the workout is uploaded to your Intervals.icu calendar, so by the time the cron checks the next day at 14:00 the entry was always already gone. The check now reads the actual Intervals.icu calendar for yesterday — which also means workouts uploaded outside the daily-plan path (TrainNow, manual edits, Coach+ adjustments) now count as "planned" for nudging purposes, and the message body cites the real workout name from the calendar ("you skipped yesterday's Threshold Intervals") instead of a generic category label.
  • New: Three new proactive Coach+ nudges (Pro/Max) — a "goal at risk" mid-week check, a "tomorrow asks a lot from you" evening prep, and a "tomorrow you move into a new phase" heads-up. Each nudge opens Coach+ pre-filled with the matching question (e.g. "what should I eat tonight and tomorrow morning before VO2max Intervals?") so the push is one tap away from a useful conversation, not a dead-end notification. Goal at risk fires Wed/Thu/Fri at 14:00 when the projected CTL is at least 5 points behind your target and the goal is still 4+ weeks out — and once we've pinged you, we go quiet unless the gap actually worsens by another 2 CTL (and stop entirely after 3 pings for the same target), so a persistent "you're a bit behind" state doesn't turn into weekly spam. Tomorrow's hard session fires at 19:00 when tomorrow's scheduled workout exceeds 60 TSS or 90 minutes (catches both threshold/VO2max days and long endurance rides). Phase transition fires at 19:00 the evening before any phase change (Base → Build, Build → Peak, Peak → Taper, Taper → Race Week) so the next morning's shift in workout shape doesn't come as a surprise. All five nudge types share a one-push-per-day cap and respect your existing `coachingNudges` push toggle — disable in Settings if you'd rather not get them.

Saturday, May 16, 2026

  • Fixed: Setting "Improve FTP" as a training goal now actually saves. Two reports converged on the same root cause: Zaid set "improve FTP, target 250" but the Peak Form Progress widget kept showing his Intervals.icu manual FTP — admin data confirmed no goalCtlConfig / goalFtpConfig had been written. Sebastian (DE locale) reported that clicking "Weiter" on FTP Improvement dumped him back at the template selector. The shared cause: the goal-setup wizard's template picker preserved the slider duration when switching templates, so a user moving from off-season-base (default 16 weeks, max 24) to FTP Improvement (max 12 weeks) silently sent 16 weeks to the server, which rejected the save with a German validation error easy to miss. The fix clamps the carried-over duration into the new template's [minWeeks, maxWeeks] range. The wizard's final save step also got a fail-loud check: if the CTL/FTP wizard data never finished loading, clicking Finish used to silently no-op (leaving Zaid thinking he'd saved 250); now it surfaces a load-error toast so the athlete knows to retry.
  • New: Walk and Hike are now first-class goal-event sports. Set the Camino de Santiago, Vierdaagse Nijmegen, Kennedy Mars, multi-day Alpine treks, Kilimanjaro prep, or a local charity walk as a goal on your Intervals.icu calendar and IntervalCoach will detect it, generate a time-on-feet-focused plan with a new GOAL_HIKE phase model (12-week Build → 4-week Peak with the longest walks and any back-to-back days → 2-week Taper so you show up rested), and prescribe walking sessions on the days your schedule allows them. There's also a new "Long Walk / Multi-day Hike" non-race goal template if you don't have a specific event on the calendar — choose it in Settings → Goal, set a duration of 8–24 weeks, and the planner ramps your time-on-feet by 15% above your current CTL. Detection covers Camino, Vierdaagse, Kennedy Mars, Kilimanjaro, Everest Base Camp, GR20, West Highland Way, Moonwalk, Wanderung, randonnée, escursione, trilho, and a long list of localised pilgrimage / charity-walk patterns across 12 languages.
  • New: When the daily readiness check flags suppressed HRV or the "low motivation + high stress" combination, IntervalCoach can now swap today's planned ride or run for a walk instead of just dialing back the intensity. The swap only happens when you have Walk on your training schedule for that day — if Walk isn't in your allowed sports the recommendation stays advisory: the coaching note tells you a walk would be the better answer today and how to unlock the swap (Settings → Training Schedule), and the intensity scaling / cooldown extension / stimulus swap that were already there continue to work just like before. Race days and goal-event days are never swapped. The new walk inherits the planned slot (same day, the original workout gets cleaned up off the calendar), gets uploaded as a Walk activity so your watch syncs it correctly, and the workout description starts with the *why* — e.g. "HRV suppressed — active recovery and sleep hygiene recommended" — so you can see at a glance what the signals are doing.
  • New: Schedule walks and hikes in your weekly plan. Walking and Bergwandeling are now toggleable sports in Settings → Training Schedule alongside cycling, running, swimming and strength. When a day is set to Walk or Hike, the planner generates a duration-based session for that day (15 TSS/hour for walks, 25 for hikes, matching the load floor for completed activities), and uploads it to Intervals.icu as the right activity type. Useful for athletes mixing walks into a recovery week, athletes returning from injury who want low-impact volume, or anyone training for a long hike or charity walk. Today's adaptive workout (daily cron) also routes walk/hike days through the new simple-generation path — no AI rewrite, no power/pace targets, just time on feet with a Z1-Z2 HR recommendation. The Training Demand and Training Volume sections on the Training Plan page now sit next to each other since they're two zoom levels of the same thing.
  • Fixed: The Training Plan day grid now shows every stage of a multi-day goal event (stage races, weekend tours), matching what the calendar already shows. Previously, only the first stage rendered — a Friday + Saturday "fietsweekend" goal would show Friday as the race row and Saturday as an empty "+ Add" slot, even though both events existed on your Intervals.icu calendar. Root cause: the training plan was fetching events up to the goal's *start* date (the periodization anchor), so any sibling stage on a later day got silently filtered out before the day grid was built. The fetch upper bound now extends through the goal's end date — single-day goals are unaffected.
  • Fixed (iOS): The IntervalCoach iOS and Mac apps no longer ask you to reconnect to Intervals.icu after every app update, and your Settings → Active sessions list no longer fills up with one stale row per build. Two underlying problems: (1) the iOS Keychain entry holding your session token was stored without an explicit access group, so each app update (and on Mac Catalyst, each cold launch) re-keyed the slot and the previous token became unreadable — forcing you back through the Intervals.icu OAuth flow. The token is now bound to a stable App Group keychain access group with `AfterFirstUnlock` accessibility, plus a one-time migration that picks up your existing unscoped token on first launch so you don't get prompted to reconnect when you install this update. (2) The backend recorded a fresh session row for every token mint, with no dedup, so even users who weren't affected by the Keychain bug saw the device list grow. Same-device re-auths now upsert the existing row (keyed on iOS major.minor) instead of appending. Reported by Mark Hulskamp on the Intervals.icu forum (post #771); same root cause as the iPad-on-Mac "reconnect on every launch" complaint.
  • Fixed: Coach+ can now move club rides, training crits, and other unstructured rides on the calendar — not just structured workouts. Asking "it's raining, move today's Zaterdagtraining to tomorrow" used to fail because the reschedule tool only matched WORKOUT-category events with a non-empty description, so a C-race entry (club ride / training crit) or an unstructured WORKOUT placeholder was silently rejected and the assistant would fabricate a "no movable workout on the calendar" reply instead. Auto-detection now also picks up C-races and WORKOUTs with no description, preferring the planner-placed structured workout when both share a day. Moving an A or B goal race still requires you to ask by name — the chat names the race and its priority in the confirmation reply so you see exactly what you're approving.

Friday, May 15, 2026

  • New: Generate a walk or hike on demand via TrainNow. Pick Walk or Hike in the sport selector, choose a duration, and get a simple endurance session — no interval structure, no ERG targets, just time on feet with a Z1-Z2 HR recommendation in the description (Z1-Z3 for hikes so climbs aren't capped). Uploads to Intervals.icu as a Walk or Hike event so your watch picks it up like any other workout. Estimated TSS matches the per-hour floor used for completed walks/hikes (15 TSS/hour for walks, 25 for hikes) so the planned and actual numbers line up.
  • New: Walk and Hike activities now count toward your weekly training load. Apple Health and Strava strip the HR/power streams when they push a walk or hike to Intervals.icu — which left Intervals.icu unable to compute TSS, and a 90-minute walk would show as 0 TSS on your dashboard even though it's legitimate aerobic work. IntervalCoach now applies a conservative duration-based floor: walks get 15 TSS/hour, hikes get 25 TSS/hour (the elevation makes hikes a bit more demanding). When Intervals.icu has computed a higher value from HR streams we use that instead. The numbers are deliberately on the low side — for most fit athletes walking sits below Z1, and we'd rather under-credit than inflate weekly load with phantom stress. Recent activities, the dashboard today-TSS, and the upcoming-calendar all recognise walks and hikes with their own icon. This is the first step of broader walking/hiking support — TrainNow, recovery-day prescribing, and walk goal events come in follow-up releases.
  • New: Delete a planned workout straight from the calendar. The race detail dialog had a Delete button; the workout detail dialog never did, so the only way to remove an AI-generated session you didn't want was the Training Plan page or a Coach+ chat (which costs credits). Open any planned workout from the calendar and you'll find the same Delete option on the footer; it writes through to Intervals.icu just like the Training Plan delete and the race delete.

Wednesday, May 13, 2026

  • Fixed: Apple Health workouts that already reached Intervals.icu through another source (Strava, Garmin Connect, Wahoo, Polar, etc.) no longer show up as "Failed" in the iOS sync log. Intervals.icu's own dedup compares the file bytes — same workout coming from two different sources arrives as two different files, so its dedup misses, and our upload was rejected as an overlap with the existing activity. The HealthKit uploader now checks the calendar for an existing activity at the same start time (±5 min, with a 30% duration tolerance to guard against unrelated sessions sharing a slot) before pushing the file. When it finds one, the upload short-circuits and reports back as "already synced" instead of "Failed". Also softened the residual unknown-failure copy in the iOS sync log to mention that the workout may already be on Intervals.icu from another source — useful for the edge cases the dedup check doesn't catch. Reported by Shaun Edwards.
  • New: Your Intervals.icu workout library is now part of the inventory I pick from (Pro/Max). For athletes who've spent time curating workouts in Intervals.icu — coach-built sessions, purchased packs like High North Performance, or your own favourites — those workouts now appear in the TrainNow Library tab alongside the catalog templates, and more importantly, they're treated as peer candidates whenever I'm picking a workout for you: daily cron, rolling workout updates, weekly plan generation. When your library workout matches the slot within ±10%, I upload your version verbatim. Outside that, the AI scales warmup, cooldown, and inter-interval recovery to fit your time — without touching the work intervals (number of reps, work duration, intensity targets), so the hard part of your authored workout stays exactly what you wrote. To make periodisation work, each library workout is matched to its closest catalog twin (same sport + intensity bucket, closest TSS/hr) and inherits its phase fit — so a VO2max-style library workout is treated as primary in Build phase and avoided in Base, just like the catalog's own VO2max sessions, rather than competing against them blindly. No setup needed: once your Intervals.icu connection is refreshed with the new library scope, your library is auto-detected and cached for 24 hours. If a rewrite ever fails for some reason, the planner falls back to a matching catalog template — you never get a broken workout.
  • Fixed: Calendar mutations now appear instantly without a manual refresh. Drag-and-drop a workout to a new day, edit/delete a race, create a new race or workout — the calendar reflects every change immediately and a silent background reconcile follows up so any optimistic-update edge case (cross-month drag, day-plan move when the source and target are in different month buckets, server-side TSS recompute) self-heals within one round-trip instead of showing stale data until the page reloads. No more full-page loading spinner on every save either — the refresh runs invisibly.
  • Fixed: Daily Outlook and the calendar workout no longer disagree when you're a few days back from a sick or injured stretch (or any other signal that gradually decays over days). The dashboard was correctly saying "MODIFY: 50% TSS, cap Z3" because the readiness assessment saw the recent injury return signal plus a fitness projection that had drifted off target — but the calendar workout stayed at full intensity. Root cause: the morning pipeline has two stages, an early event-agent check that decides whether to regenerate today's workout, and a later recovery agent that produces the full readiness narrative. The event-agent's adaptation gate was running a stripped-down readiness compute that silently dropped signals like "returned from injured", "fitness projection at risk", chronic-fatigue, monotony / strain, and the daily wellness check-in. So the gate concluded "no change, keep the workout" while the dashboard outlook (driven by the full pipeline downstream) said modify. The event-agent now reads the same pre-assembled signal inputs the recovery agent already uses, so both stages see the same picture and the calendar matches what the dashboard is asking for. Reported by Marco Baiocco (recurring complaint, 3rd round — first two had different code paths fixed earlier; this was the remaining gap).
  • Fixed: Coach+ no longer shows the red "retry" pill on answers that streamed in completely. After a successful answer, a follow-up cleanup step (a tool result that finished after the visible text, a late socket close, etc.) could throw an error that the AI SDK surfaced on the chat hook — the panel then rendered the retry affordance regardless of whether you already had a usable reply on screen. Reported by Max user Marc, who tapped retry on what looked like a partial answer multiple times before realising the response was already complete and the retries were silently consuming credits. The retry pill is now suppressed when the most recent assistant message already carries non-empty text, so genuine mid-stream failures still get the retry button while benign post-stream errors stay invisible. Those suppressed errors are still reported to Sentry as warnings (tagged INT-1165) so we can keep chasing the underlying cause without degrading the chat experience in the meantime.

Tuesday, May 12, 2026

  • New: Full in-app race management — create, edit, and delete race events without leaving IntervalCoach. A unified "+ Add" picker appears inline on each day in the training-plan week table, and as a hover-only "+" in the top-right of every future day on the calendar; clicking it gives you Workout or Race as options. From any race event (click its row on the training plan, its card on the calendar, or its tile on the dashboard) you can edit name, date, start time, priority (A/B/C), sport, indoor/outdoor, distance, target time, and load (TSS) — the same fields Intervals.icu's own "Edit Calendar Entry" dialog exposes — or delete the race entirely. Every change writes back to the same event on Intervals.icu (no local-only state to drift out of sync), and invalidates the calendar / training-plan / event-detail caches so the rest of the app reflects the change on the next page interaction without waiting for a manual refresh. Race events in the event-detail dialog also got a visual refresh: a large colored A/B/C priority badge replaces the generic trophy avatar, and the stats grid shows Distance / Target Time / Load (the three numbers an athlete actually wants at-a-glance) instead of duration / TSS / sport.
  • Improved: More variety in the workouts you get. The rotation system that should pick different workout templates from week to week was quietly broken — for most athletes it kept landing on the same handful of templates out of the 130+ in the catalog (e.g. always the same VO2max 5×3min, always the same sweet-spot template, almost never a dedicated long run). Rotation now works, so you should start seeing more variety: different VO2max protocols, sweet-spot variants, longer-tail run sessions, and weeks that don't repeat the same workout back-to-back.
  • Improved: Agent Log now keeps the last 60 days of training decisions instead of 14, so you can look further back to see why a workout was chosen.
  • Improved: Agent Log groups pre-planned future workouts under the day they were decided, not the day they'll happen. Previously a Saturday ride generated today would show up under Saturday, which was confusing — now it shows under today (with "for Sat, May 16" in the entry) so you can see in one glance "this is what the planner decided today." Each entry also surfaces the actual reason the planner picked that workout (recency rotation, focus area, training phase) instead of a generic "rolling fill" label, plus a bulleted list of every modifier that influenced the score — variant rotation, weak-zone focus boost, weekly TSS plan, time-crunched preferences, recovery overrides, and so on — and the top alternatives that lost. So instead of just "Optimal Taper phase workout", you might see "Optimal Taper phase workout · Variant rotation: sibling in threshold group already selected this week · Also considered: Sweet Spot, VO2max Short".
  • Fixed: Race-week and pre-race-taper plans no longer schedule ~2× the appropriate workout volume around your race. The per-day TSS allocator was scaling each session down correctly to fit the small budget left after the race itself is deducted from the weekly target — and then a separate "physiological minimum" step would immediately bump every session back up to the endurance baseline (45 TSS/hr for a Ride, similar for other sports), wiping out the taper. Concretely: an A-race week with a 259 TSS weekly target and a 229 TSS race on Sunday should leave ~30 TSS for the week's workouts (one short opener mid-week, one short pre-race openers session); the planner was producing ~86 TSS instead. Two underlying bugs: (1) mid-week easy workouts in race weeks were tagged as "endurance" category, so the floor compared against the endurance rate instead of the lower recovery rate; (2) the floor's "shorten duration instead of bumping TSS" branch only triggered for sessions longer than 90 minutes, and race-week sessions are almost always ≤ 90 min — so it always bumped TSS upward. Now race-week and pre-race-taper non-intensity workouts are tagged as recovery, and the floor always prefers shortening the duration over raising the TSS during tapering weeks — so a 60-min easy ride with 15 TSS of budget becomes a 20-min easy ride rather than a 60-min ride forced to 45 TSS. Net effect for your race week: shorter, easier sessions that respect the taper, no more "the planner gave me a hard ride three days before the race" surprises.
  • Fixed: VO2 max running intervals no longer use a too-hard recovery jog between work bouts. The template prescribed jog recovery at the top of the easy band (~77% of threshold pace) — that lands in low Z2 / endurance pace, so heart rate barely dropped between reps and the next interval started with reduced VO2 headroom. Recovery now uses E-pace jog (mid/low easy band, ~65% threshold pace) per Daniels' Running Formula prescription for I-intervals, so HR has room to recover and each work bout pushes back near VO2max.
  • Fixed: Cycling threshold workouts now respect periodization phase. Long L4 reps (e.g. 3×20 at FTP) are the classic Coggan/Allen peak-phase prescription, but the generator could emit them for any rider with a long enough session — including riders still in their base phase, where shorter reps and lower total L4 volume are appropriate. Reps are now phase-gated: Base caps at 10-min reps with 30-min total L4; Build caps at 15-min reps with 45-min total L4; Peak/Race/Taper unlocks the classic 3×20 / 60-min envelope. Recovery between reps also scales with rep duration (5 min for 10-min reps, 8 min for 15-min reps, 10 min for 20-min reps) — the Coggan/Allen 5-10 min recovery range was previously fixed at 5 min regardless of rep length.
  • Improved: The Health card no longer shows an "AI load advice: reduce" entry alongside the underlying wellness signals that drove it. That entry was a conclusion masquerading as a signal: the same AI prompt consumed TSB / ramp rate / HRV / sleep / recovery and emitted a categorical verdict, which then appeared in the signal list next to the very observations that produced it — three lines saying the same thing when fatigue stacked. The verdict-as-signal was also a black-box decider (you couldn't see why "Reduce" was picked) and added an extra LLM call per readiness compute. The same intent is now expressed as a rule in the signals engine: when ≥2 wellness warning signals (HRV / RHR / sleep / recovery) fire together, the compound itself triggers the load reduction the AI used to drive (TSS × 0.85). Each signal still shows up under its own axis, but you no longer see the synthesised "AI says reduce" line on top of them. Also: a sustained-RHR-elevation signal that fired but had no rule attached (so the load engine ignored it) now correctly caps intensity at Z3.
  • Fixed: Agent Log on iOS no longer shows raw translation keys ("reasons.phaseWorkout|Taper") and bare workout slugs ("endurance", "enduranceWithPickups", "threshold") instead of readable text. The web /decisions page translated those client-side via the next-intl `t` function and the workout catalog's display names; the iOS Agent Log has no translator, so it rendered the raw values straight from the API. The /api/decisions response is now localized server-side using the athlete's saved language — reasons render as "Taper phase workout" / "Taper fase training" / etc., and workout slugs resolve to their catalog display names ("Endurance + Pickups", "Threshold"). The web /decisions page already pipes the response through its own translator + name formatter, which now become no-ops since the strings arrive already formatted.

Monday, May 11, 2026

  • New: Agent Log is out of beta and on for everyone — free, trial, Pro, Max. It's a timeline of every coaching decision behind your training: today's readiness call, why this workout got picked, what changed when fresh wellness data arrived mid-morning, every adaptation you approved or skipped, and everything Coach+ did on your behalf. If you've ever wanted to know "why did it pick that workout?" — this is the answer. Find it in your account menu as "Agent Log". Keeps the last 14 days.
  • New: Brick workouts on JustTrain. A Brick option now sits alongside Ride / Run / Swim / Strength on JustTrain. Pick a pattern — "Transition" (sweet-spot bike → short Z2 run, trains running off the bike) or "Long endurance" (Z2 ride → Z2 run, race-day pacing under fatigue) — choose ride and run durations, and the coach generates both halves at once and uploads them as two back-to-back calendar events with a short transition gap between them. Useful for triathletes rehearsing the bike-to-run transition, and for anyone who runs after riding (multi-sport day, off-road events, general fitness). Daily-cron and weekly-plan integrations come in follow-up phases.

Sunday, May 10, 2026

  • New: Web Settings → Integrations now has a "Manage on Intervals.icu" shortcut that takes you straight to intervals.icu/settings/connections, where you connect Garmin, Strava, Oura, Polar, Coros, Suunto, Hammerhead, ROUVY, MyWhoosh, Dropbox, Google Health Connect and the rest of the Intervals.icu integration list. The structured workouts I generate already land in your Intervals.icu calendar — once Garmin Connect (or Wahoo, Polar, Zwift) is linked there, every workout shows up on your device on the right day, ready to follow with step-by-step targets. The iOS app got the same shortcut a week ago; this brings the web app to parity.
  • Fixed: When you ask Coach+ to build a custom workout with cadence targets — "70-80 rpm hill simulation", "low-cadence sweet spot at 60-65 rpm", "high-cadence drills at 95+" — the cadence target now reaches the resulting Intervals.icu workout instead of being silently dropped. The chat tool that builds custom workouts had no slot for a cadence value in its segment schema, so even though the underlying workout format and Intervals.icu DSL both support per-segment RPM, the request never made it past the tool boundary. Coach+ would build a structurally correct workout, upload it, and the rpm annotation would be missing from every step — so when the workout reached Zwift or your head unit, no cadence target appeared. The schema now accepts an optional cadence per segment (40-140 RPM, cycling only — silently dropped on Run/Swim segments since pace-based sports do not carry an RPM target on Intervals.icu). Reported by Jos Janssen.
  • Fixed: Dashboard responses, daily-workout generation, and Sunday-evening weekly summaries no longer queue up behind a slow internal cache. The dashboard pipeline was rewriting the rendered health-card signals back to cache on every page load — same value, multiple times per athlete per day — and Vercel's Runtime Cache started hanging on those repeat writes for athletes in the Frankfurt region a week ago. Each hang held the cache call open for 5 seconds, dragged any other cache writes in the same request along with it, and held the QStash worker slot for daily-workout / weekly-summary jobs longer than it should — so the queue grew faster than it drained, and Sunday-evening weekly summaries never fired before the cron window closed. The fix is a generic "skip the write if the value didn't change" guard at the cache layer (~95% of repeat writes for this dataType collapse to zero), so the cache backend stops being asked to do work it doesn't need to do. Throughput on the AI-task queue is back to normal and the daily / weekly emails resume their usual schedule. The pattern is reusable, so other rewrite-heavy cache keys can adopt it as we audit them.
  • Fixed: Dashboard "Week TSS" ring no longer falls to 0% when the Sunday weekly-plan cron runs late. The canonical state was rejecting any stored weekly plan generated more than 7 days ago as "stale" — even when the plan still covers the present week and is perfectly correct. So when the Sunday-evening regeneration cron failed to fire on time, exactly 7 days after the previous run the dashboard would simultaneously flip Week TSS from a real percentage to 0%, hide the readiness assessment, and stop the goal-projection card from rendering. Validity now keys off whether the plan's weeks[] array still has an entry matching today's Monday (with a usable weeklyTSSCapped fallback when it doesn't), regardless of when the plan was generated. The goal-projection card uses the same policy. A late cron no longer black-holes the dashboard until the next regeneration lands.

Saturday, May 9, 2026

  • Fixed: Health card no longer flags "7 consecutive training days" as a warning for athletes whose training schedule has all 7 days enabled by design. The detector was firing whenever consecutive-day count crossed 5, with no awareness of the athlete's declared schedule — so a triathlete training every day on purpose got the same yellow warning as someone who normally rests Wednesday and Sunday but hasn't this week. The detector now suppresses the warning when the schedule has zero rest days configured (it's the athlete's plan, not an alarm bell). Other fatigue signals (TSB, chronic fatigue, ramp rate, monotony) still cover actual overtraining, so removing this one signal for 7-on athletes doesn't blind the system. Reported by Giuseppe Leccese.
  • Fixed: Picking the "Tempo" category in TrainNow for a swim now generates a tempo swim workout instead of a threshold one. The category-to-workout map had both Tempo and Threshold pointing at the same `swimThreshold` workout type for swimming, even though a separate `swimTempo` template exists in the catalogue. Reported by Giuseppe Leccese — picked Tempo in the iOS app, got a CSS-pace threshold session called "Soglia Nuoto". Now picks the right one (Z3 pace, aerobic, moderate intensity).
  • Fixed: Post-workout analysis no longer labels a flat Z2 ride as anaerobic just because the prescribed workout was called "Sprints". The internal stimulus classifier was checking the workout name first and short-circuiting before it ever looked at IF or zone-time data — so a 41-minute easy spin against a Neuromuscular Sprints prescription came out the other side as "anaerobic, 7/10, you targeted weak anaerobic zones." Reordered the classifier to data-first: zone-time data (which is robust to warmup/cooldown dilution because it counts seconds in zone, not averages) is checked first, then IF, then the name as a final fallback when no power/HR data is available. Existing legitimate cases still work — a real threshold session with warmup/cooldown still hits the zone-time threshold cleanly. The fix also reaches the AI narrative path: the prompt is fed the data-derived stimulus, so the language stops anchoring to the prescription when execution diverged. INT-1131 reported by David Ward.
  • Fixed: The pre/during/post-workout nutrition advice on the calendar event detail dialog now renders in your selected language. The event-detail API was calling the nutrition service without passing the athlete's language, so it defaulted to English regardless of whether you had Spanish, French, German, etc. selected. Other surfaces (daily email, TrainNow, Coach+ chat tool) were already passing language correctly — only the calendar dialog was affected.
  • Fixed: Coach+ now appears in the sidebar consistently after sign-in. The /api/flags endpoint was serving its anonymous empty-flags response with Cache-Control: public, so the Vercel CDN could replay it to a freshly-logged-in browser whose marketing browse had primed the cache — flags came back as {} for up to five minutes and Coach+ (and Training Plan) silently disappeared from the navigation. Anon responses are now Cache-Control: private, scoped per-user. Also retired the redundant "chat" feature flag; Coach+ availability is enforced by your tier's monthly message quota, not a flag.
  • Fixed: Weekly-plan entries in the Agent Log now appear under the date the planner actually decided — not under the future week being planned. Three bugs combined to make the audit log misleading: (1) entry.date was set to the upcoming week's start (so a Race Week plan generated last Sunday landed under "Monday May 25" instead of last Sunday); (2) the dedup key was date+type, so all weeks of a multi-week plan written in one cron run raced against each other on KV and only the last one survived (parallel writes, last-write-wins); and (3) the per-week dayPlan filter used string concatenation for the week's end date that broke at month boundaries (May 25 + 6 days computed as "2026-05-31" only because of luck — May 26 onward would have produced "2026-05-32"). The cron now writes one entry per planned week with date = decision day, the dedup key includes weekStart so the entries coexist, the dayPlan filter uses real date math, and weeks beyond the rolling dayPlan window fall back to the athlete's configured session count and sports instead of rendering as "0 sessions". The summary line now shows "week of <date>" so the planning subject is still visible.
  • Improved: Agent Log now shows the full 14-day history instead of only the most recent ~14 entries. The API's response limit was clamped at 14 even though storage retains up to 100 entries — and with five-plus decision types per day (readiness, workout selection, load adjustment, post-workout, wellness re-checks) that meant the log only ever showed about two days of activity. Cap raised to match storage.
  • Improved: Agent Log entries now show a timestamp and a meaningful summary for the wellness re-checks that fire when your wearable syncs. Previously every "Re-checked after wellness" entry rendered as a blank row in the timeline — the summary line had no handler for that decision type and there was no time on the row, so you couldn't tell whether a check happened at 8am (and got suppressed because it landed before the 10am-5pm re-check window) or mid-afternoon (and actually evaluated). Each row now carries an HH:MM timestamp on the right and a one-line outcome label like "Re-checked — outside re-check window" or "Re-checked — no material change". Also collapsed the nested "Agent trace" dropdown inside expanded entries — the trace data renders directly now, one less click to see what the agent saw.
  • New: Daily email timing — "After HRV and sleep sync" option. For athletes whose Garmin or Wahoo syncs after their preferred email time, the daily briefing used to fire blind to today's wellness data — sometimes hours before HRV / sleep had even landed. Pick the new "After HRV and sleep sync" option in Settings → Notifications and the email is held until both fields arrive from your wearable, with an absolute 11am-local fallback so the email always goes out by mid-morning even if data never shows up. Whoop users effectively had this behavior already (Whoop's recovery webhook drives the cron in real time); the setting now makes it explicit and migrates them onto the same toggle. Available on web and iOS.
  • Fixed: When a Coach+ stream errors and you tap to start a new conversation or switch to another existing one, the red "tap to retry" banner no longer hangs around. The retry state was tied to the previous conversation's failed request, so the new conversation's welcome screen would show a banner pointing at a request that was no longer relevant — and tapping it would re-fire the old conversation's message in the new one.
  • Improved: When "Preview before applying" is on and the morning cron stages a workout swap, every surface now agrees this is a proposal awaiting your approval — not a done deal. The daily briefing's training-vandaag card flips from the green checkmark "Workout adapted" framing to an orange hourglass "Workout proposed" header. The daily email swaps the "⚡ Workout Adapted" badge for "⏳ Workout Proposed". The dashboard's Today's Plan card gains a "Voorstel" pill in the header so you don't miss that there's a decision pending below. Previously the briefing, email, and dashboard all rendered as if the swap was already applied, while the calendar still had the original workout — confusing if you opened the app expecting your scheduled session and saw a different one in the briefing instead.
  • Improved: The pending-adaptation card now shows the proposed workout next to the original so you can compare before approving. Previously the card listed only the original ("Originally planned: Lange duurrit · 114 TSS") but never told you what would replace it, so the only way to judge the swap on its merits was to approve and find out. The card now stacks the original (struck through) above the proposal (with name, TSS, and duration) — same data the email and dashboard already had, just surfaced where the decision is being made.
  • Improved: The Approve and Keep original buttons on the pending-adaptation card no longer take up half the card height. Replaced the matched pair of full-width primary buttons with an asymmetric layout: Approve stays a primary capsule pill in the accent color, Keep original drops to a quieter ghost-style text button beside it. The card reads as "approve this, or keep things as-is" instead of two equal-weight choices fighting for the tap.
  • Fixed: The "Why" bullets on the pending-adaptation card now show the same signals as the dashboard Health card and the daily email instead of the full readiness audit. Previously the proposal listed every factor the readiness pipeline considered ("Training load balanced", "Chronic fatigue risk low", "Subjective wellness normal" alongside the actual trigger like "Aerobic efficiency declining") — so the card read self-contradictory: most lines said "all good," only one or two flagged the real reason. Now the Why is sourced from the live signals engine filtered to actionable warnings, so the three surfaces (email pills, Health card, pending Why) tell one story. Existing pending entries from before this fix still carry the old factor list until they're approved/rejected and a new one is generated by tomorrow's cron.
  • Fixed: The dashboard's pending-adaptation approve/reject card now renders on first paint instead of waiting for the secondary data fetch. Behind the scenes the base /api/dashboard route was leaving the field undefined while only the deprecated /api/dashboard/extended route populated it — so the card showed up a beat late on slow connections, and on the new split endpoints (which the iOS app and the new web flow use) it could miss entirely. The pending entry now lives in the shared dashboard service, so every consumer sees it consistently.
  • Fixed: Tapping the inline "Open om goed te keuren" hint on the workout card now scrolls to the approve/reject buttons instead of doing nothing. The hint text was rendered as plain copy that looked like a CTA — athletes tapped it expecting the approve flow and got no response. Wrapped in a button that smooth-scrolls to the PendingAdaptationCard above when there's a pending proposal.
  • Internal: Cleaned up duplicate "Voorgesteld" badge that was rendering both inline on the workout card and as the full PendingAdaptationCard above it. With the full proposal card showing reasoning and Approve/Reject buttons, the inline abbreviated badge was redundant — same information shown twice. The inline badge now only renders for auto-mode adaptations (where there's no full card above).

Friday, May 8, 2026

  • New (iOS): Coach+ chat overhaul. Tapping Approve on a Coach+ proposal now reliably executes the action — squashed a stack of bugs that could leave approvals stuck or silently failing. Streaming feels different too: a blinking cursor and animated thinking dots show exactly when the coach is composing, fetching data, or waiting, with a Stop button to abort a long answer. When a stream fails you get a tap-to-retry banner instead of a silent dead end. A floating scroll-to-bottom arrow appears when you scroll back through a long conversation, with a proximity threshold so it disappears once you're close to the bottom and doesn't overshoot when tapped. Long-press a message bubble for Copy / Share. Tool cards render live as the coach calls them instead of popping in after the response finishes, and the approval card stays visible when it arrives mid-stream. The daily briefing's "Discuss with Coach+" button opens the coach with the right context — ask "why is today a rest day?" and the coach already knows. Accessibility labels on every icon-only button, plus a Dynamic Type cap on dense tool-card layouts so the largest accessibility text sizes don't break the structural data labels.
  • New (iOS): Daily briefing rebuilt as the deeper read of your daily outlook. Brings together the readiness signals from your dashboard health card, the training context for today, and a recommended action — all in one place — instead of scattering the same data across three different sheets.
  • Improved (iOS): Apple Health workout sync now accepts "Other" and equestrian workout types instead of silently filtering them out. Both come through with HKWorkoutActivityType values that fell outside the previous whitelist, so manually logged "Other" cardio sessions and any HealthKit data tagged as equestrianSports were never reaching Intervals.icu.
  • Improved (iOS): Stability fixes across chat, calendar caching, and background sync. Includes an idle-timeout on SSE streams that goes quiet for 45 seconds (so you don't stare at a blinking cursor indefinitely on a flaky connection), preserved conversation state across post-send loadHistory races, and corrected tool-card error rendering — failed tools now show a red ✗ instead of a misleading green checkmark.

Thursday, May 7, 2026

  • New: Coach Mode is here — invite a human coach onto IntervalCoach and they see your dashboard, can edit your weekly plan, and chat with you in Coach+. Coaches use IntervalCoach for free; you pay for Max as the athlete and the coach pays nothing on top of that. Available on the Max tier — see Settings → Coach to send an invite, or visit the new /coaches landing page for how it works.
  • Fixed: Race Week TSS targets no longer exceed maintenance load for athletes already at goal CTL. Two related bugs were combining to produce a Race Week target of 619 TSS for a user whose maintenance load (CTL × 7) was 525 — a 117% overshoot in what is supposed to be the deepest taper week of the plan. Cause: when the user is already at target CTL the planner uses an "overshoot" path (1.10× effectiveGoalTSS) to keep CTL on target through the upcoming taper decay. effectiveGoalTSS is itself inflated to compensate for periodization overhead, so for plans heavily weighted toward Race Week / Taper (small planMultiplier), inflatedGoalTSS can be ~2× maintenance. The 0.5 Race Week multiplier on top of that still leaves the target near or above maintenance — and the existing peakBaseTSS freeze cap (INT-573) didn't catch it because Build/Peak weeks in the same plan share the same inflated weekBaseTSS, so peakBaseTSS picked up the same inflated value. Race Week and Taper weeks are now hard-capped at currentMaintenanceTSS (CTL × 7) on top of the existing peakBaseTSS check. By definition the taper should reduce volume below the athlete's sustained-load baseline; the cap encodes that invariant.
  • Fixed: Event-deduction logic in the planner is now aligned with the plan eval and applied before availability capping. Two related bugs were producing peak weeks with a heavy A/B race that under-built the remaining sessions: (1) the planner used the scheduled training duration on the event's day-of-week to estimate the deduction (and skipped entirely when that day was a usual rest day), while the eval used the event's actual moving time — so a goal race on a Saturday rest day produced a weekly plan with no deduction on the planner side but a 540 TSS deduction on the eval side, flagging it as catastrophically under-target. (2) The deduction was applied after capping the periodized target by available training hours, which double-counted the deduction for time-limited weeks. The two surfaces now share a single calculateEventDeduction helper, the planner subtracts event TSS from the periodized target first and then caps to availability, and movingTime is propagated alongside icu_training_load so the deduction works for races/manual workouts that don't yet have an explicit TSS attached.
  • Internal: The maxNonAdjacentSlots helper that decides how many intensity sessions can fit in a week without two landing on adjacent days now lives in a single shared module (lib/services/intensity-spacing) consumed by both the planner and the plan eval. Previously each side had its own copy. No behaviour change — the planner already produced the right intensity count and the eval already graded against the same brute-force cap; this just makes it impossible for the two to drift apart later if someone changes the rule on one side.
  • Fixed: The "[Weekly Plan - X]" phase tag in workout descriptions now matches the weekType your dashboard shows. The rolling-workout generator that builds workouts up to a week ahead was preferring the macrocycle phase ("Taper", "Build") over the canonical weekType ("Peak", "Recovery", "Race Week") when both were stored on the week entry — so an athlete on a Peak weekType could see "[Weekly Plan - Taper]" in the workout description even though their dashboard, daily briefing, and stored plan all said Peak. The two fields can legitimately differ (a Recovery week within a Peak phase, for example) and weekType is the user-facing one, so it now wins. The fix only affects newly-generated workouts; previously-uploaded ones keep the stale tag they shipped with until they're replaced by the next adaptation cycle.
  • Fixed: Daily workout selection AND the rolling weekly-plan generator now respect your zone-progression diagnosis instead of being silently overridden by the macrocycle phase descriptor. The selection layer applies a +2 score boost to workouts that match your weakest zones (the focusAreas set in your zone progression — vo2max, threshold, anaerobic, etc.). But the boost was getting wiped out for Peak / Taper / Race Week weeks because those phases pass non-zone descriptors ("peak", "taper", "racePrep") into the same focusAreas slot, and the code used those descriptors first while ignoring the actual zone diagnosis. Result: an athlete diagnosed as weak in VO2max would still get threshold-heavy Peak weeks. The resolver now drops non-zone descriptors and merges the phase emphasis with the diagnosed weaknesses, AND the rolling-workout generator (which builds workouts up to a week ahead) now fetches zoneProgression and passes it into the same resolver — so a Peak athlete weak in VO2max actually sees VO2max workouts get the boost across both the immediate-day pick and the advance schedule.
  • Fixed: Weekly-plan intensity sessions no longer get scheduled on your longest day of the week. The picker that decides which days carry intensity vs. easy work was starting from the longest-duration day and then spacing the others around it — so a runner with a 90-minute long Sunday run would consistently get that day flagged as intensity, and the plan eval would correctly call it out ("the longest run is an intensity session"). The picker now sorts by ascending duration: shorter days are picked as intensity, longer days are reserved for endurance. The change is schedule-agnostic — there is no hardcoded Tue/Thu assumption — so an athlete who trains Mon/Wed/Fri/Sat with a long Saturday ride gets intensity on the three midweek 60-minute days while Saturday stays endurance, and the same logic works for any other configuration. Athletes with a learned intensity-day history (≥2 days from recent activity) are unchanged — that path runs first and reflects what they actually do.
  • Fixed: Weekly Peak/Build/Taper plans no longer overshoot their TSS target by 10-22%. The planner has a final per-week budget guard that scales TSS back down when the per-day allocations sum above target — but it only ran on Recovery and Deload weeks. For higher-load weeks the bug was visible whenever per-day demand exceeded target (typical for trained athletes with elevated intensity TSS/hr): the per-category scale-down would push intensity days below the endurance floor, the floor pass would bump them back up, and nothing capped the resulting weekly sum. The plan eval consistently flagged this on Run peak weeks (planned 413 vs target 338, +22%) and Run build weeks. The guard now runs on every week with a meaningful target (≥150 TSS, matching the eval's low-CTL tolerance) — on lower-CTL athletes whose periodized target is unrealistically low, the planner is still allowed to overshoot to produce a full session, since CTL × 7 underrates what their available time can absorb.
  • Improved: iOS daily-briefing push notification reorganized so the most actionable info reaches the lock screen. The title now shows duration + phase ("75 min · Build") instead of the workout name, since iOS prefixes notifications with "InterValCoach -" and truncates whatever follows — the workout name was getting cut off into "InterValCoach - Neur..." anyway. Workout name and goal countdown moved to the body where they have room to render. When a critical or warning signal fires (sick, recovery red, HRV suppressed 2 days), it takes the title slot directly so it survives the stacked / Apple Watch / collapsed-banner views where the body gets clipped — the duration + phase glance demotes to subtitle. Monitor-tier observations and positive signals (durability improving, fresh legs) stay in subtitle as before, since they don't change today's plan. Also fixed a unit-confusion bug introduced in yesterday's rewrite that was dividing the duration by 60 even though it was already in minutes (a 75-minute workout was rendering as "1 min"), and a missing-duration fallback for sprint workouts that didn't propagate actualDuration upstream — the push now derives duration from the segment list when the field is null.

Wednesday, May 6, 2026

  • Improved: The iOS daily-briefing push notification no longer drops your workout to show "4w to Mallorca 312" instead. The body now always leads with the workout context — duration, phase, and the goal countdown appended as a tail piece — so a typical workout day reads "Sweet Spot 4×8 / 75 min · Build · 4w to Mallorca 312". Anything signal-driven moves into the new APNs subtitle line above the body, glyph-tagged by severity matching the dashboard health-card: 🚨 risk for sick / red recovery / critical actionable factors, ⚠️ elevated for sustained HRV or RHR concerns, 👀 monitored for single-day observations the planner is noting but not acting on, and ✨ for notable positives like durability improving or fresh legs (TSB ≥ +7). All daily briefings now group together in iOS Notification Center via threadId instead of stacking. The previous "morning insight" picker also had two dead positive-signal IDs (good-sleep, hrv-above-baseline) that no detector ever emits, so the only fallbacks that ever fired were the goal countdown or the generic fresh-legs string — which is exactly why the goal countdown was overrepresented. The push now reuses the same readiness decision the web Daily Outlook and email coaching note read from, so all three surfaces agree on what is driving today.
  • Fixed: Run and swim workouts now prescribe pace percentages that line up with your Intervals.icu pace zones. The legacy zone bands (aerobic 70-80%, tempo 80-88%) landed in IcU's Z1 / low-Z2 for any athlete with calibrated zones — so a "Long Run · Aerobic 70% pace" with a 5:55/km threshold was rendering as 8:27/km, well below endurance pace, and a "Tempo Touch 80% pace" came out at 7:24/km when proper tempo for that athlete is 6:16-6:44/km. The base zones are now pinned to IcU's default Coggan pace bands (Z1 <78%, Z2 78-87%, Z3 88-94%, Z4 95-100%, Z5 101-115%) so a generated Long Run reads "78-87% pace" → IcU Z2, "Tempo Touch 88-94% pace" → IcU Z3, and threshold work stays where it always was. Same change applied to swim CSS percentages, since IcU's default swim pace bands match running's. Workout chart colours also gained a pace-aware classifier so run/swim segments now label as the appropriate IcU pace zone in the visualization (no more "Sweet Spot" badge on a swim tempo set). Cycling power zones were already aligned and didn't need recalibrating.
  • Fixed: "Preview before applying" daily-workout adaptations now also covers calendar-driven swaps, not just readiness-driven modifications. Previously, when the morning cron picked a different workout for today because of a scheduling reason — rest day, hard session tomorrow, race-week taper, stimulus spacing, weekly-plan deload — it uploaded the swapped workout straight to your calendar even if you had Preview turned on. Only state-driven modifies (yellow recovery + intensity cap, deep TSB, etc.) actually paused for approval. Both paths now stage the adapted workout as a pending adaptation; you approve or reject from web, iOS, or the daily email and only then does the calendar change. Approving a swap runs the same delete-then-upload as approving a modify, so there is nothing different to do on your end.
  • Fixed: Coach+ chat questions that fail mid-tool-call no longer count against your monthly chat-message limit. The original "refund failed turns" logic from a few weeks back only refunded when the response came back completely empty — but during the storm of stream errors during the deadlock incident on May 4th, many failures landed with a partially-streamed tool call attached (the LLM had started parsing tool arguments when the stream died), which the refund check was treating as a successful turn even though you saw "Something went wrong. Please try again." and got no useful answer. The check now requires the tool call to have actually reached a terminal state — a result, an error you can read, or an approval card — before it counts as a charged turn. Anything stuck in the streaming-input phase refunds the credit. If you were affected during May 4-5 and lost more credits than questions you actually got answers for, drop a note via the in-app feedback and we will top up your account manually.
  • Fixed: Onboarding now forces an explicit sport choice instead of starting on Ride. Pre-fix the web wizard pre-selected Ride and Run together, and the iOS app pre-selected Ride only — so a runner who didn't realise the sport cards were toggleable would land on a cycling-flavoured plan and not understand why the calendar kept generating bike workouts. The sports step now starts empty on both web and iOS, with the Next button disabled until at least one sport (and at least one training day) is picked. Existing users running through onboarding a second time still get their previously configured sports pre-filled. If you signed up before this fix and ended up on the wrong sport, you can replay onboarding from Settings to pick the correct one.
  • Fixed: The eFTP value on Settings → Training and the dashboard PIEKVORM card now matches the eFTP shown on the eFTP-history chart and on Intervals.icu directly. The two surfaces were reading the fitness-model SET_EFTP value (Intervals.icu only emits one of these when the underlying curve fit shifts enough to register a "change point"), while the chart and Intervals.icu read the per-day wellness eFTP, which updates after every ride. For users whose model had not emitted a SET_EFTP recently, the two could drift apart by 5-10W for weeks at a time — one user reported 275W on Settings vs. 268W on the chart. The two affected paths now both prefer the most recent wellness value (with a 7-day lookback so weekend gaps and early-morning syncs do not fall back to the stale model number), and only fall back to the model value for brand-new athletes who have no wellness eFTP history yet. Settings, the PIEKVORM card, and every other consumer that goes through getEffectiveFtp / fetchPowerCurve now agree on a single number — including workout zone calculations and any training-plan code that selects FTP via the "Use eFTP" preference. The PIEKVORM card was particularly egregious because the same function fetched both the (stale) card number and the (correct) sparkline below it, so a single component visibly displayed two different values.

Tuesday, May 5, 2026

  • New: Training Score is out of beta and on by default for every Pro, Max, and trial athlete — no flag toggle needed. A single 0-100 number on the dashboard that summarises how well you're training, with four sub-scores under the hood: Fitness Base (your current eFTP / pace and CTL relative to where you have been), Progressive Overload (whether your weekly TSS and ramp rate are actually building you toward your goal), Consistency (how closely you have hit your last few weekly plan targets), and Load Management (monotony and intensity distribution — the same Foster monotony / strain math used to flag overtraining risk). Tap the card to see the full breakdown plus a sentence on what is driving today's number up or down.
  • New: Training Score history chart on the Analytics page. Weekly snapshots stretch back to whenever you first had the score running, so you can see how the number has evolved alongside your eFTP and CTL trends — and watch a build block lift Progressive Overload while Load Management slowly compresses, then flip the other way through a recovery week. Toggle individual sub-scores on and off to isolate one component.
  • New: Post-workout email shows your Training Score change for the week. Each session's contribution is computed against your week-start baseline, so a hard interval day that lifts Progressive Overload from 62 → 68 shows "+6 this week" right in the email summary — and a session that nudged Load Management down because it stacked on top of three other hard days shows that too, before Coach+ has to flag it.
  • New: Coach+ understands Training Score. Ask "why is my Load Management so low?" or "what should I do about my Consistency score?" and the coach has the actual sub-score values, the weakest component, and the standard advice for each one in context — including a direct prompt back to your weekly plan when the answer is "you are skipping more sessions than you complete."

Sunday, May 3, 2026

  • Improved: Dashboard, calendar and analytics pages all load noticeably faster, especially the second time you open them in a session. A round of plumbing work this week migrated almost all transient page data onto Vercel's near-instant Runtime Cache instead of going to a separate cache server in another region (cuts read latency on the slowest 1% of requests from ~750ms to ~5ms), trimmed 48 redundant cache-bust calls per activity webhook so the cache actually stays warm between page opens, and added caching for two Intervals.icu endpoints that the dashboard was hitting on every single load (your athlete settings + your eFTP marker history). Net effect per dashboard open: 1-2 fewer round-trips to Intervals.icu, far fewer cache misses, and the long-tail "first load after a webhook" case is now almost as fast as a warm load. No behaviour changes — same data, same numbers, same calculations, just with the slow paths cleared out.
  • Fixed: The weekly plan no longer jumps straight back to a full Build week as soon as a SICK / INJURED marker drops out of the previous week. Recovery from illness takes longer than seven days, but the planner only looked one week back — so an athlete who was sick three weeks ago could come off two reduced weeks and immediately get hit with a full 1170 TSS Build week, often pushing them straight into TSB -30+ territory the system would then warn about after the fact. The planner now scans the last three weeks for SICK / INJURED events and ramps the next Build weeks back progressively: ~55% target the week immediately after illness (unchanged), ~75% the second week, ~88% the third week, full target from week four. The intermediate weeks are labelled "Post-Illness Build" so it is clear in the calendar why the targets are lower than your fitness alone would suggest.
  • Fixed: B races no longer get a full A-race taper. Previously a B race 3 weeks before your A goal would carve out two full Taper weeks before its own Race Week (e.g. ~455 TSS each in a 670 TSS Peak block), which dropped CTL noticeably and made every B race in a series eat 2.5–3 weeks of training. The FAQ has always documented B races as a 1-week taper, not the full 14–21 day Mujika window — but the phase-derivation code anchored on the nearest A or B race, so B races silently inherited A treatment after the INT-1037 refactor. Now phase derivation only anchors on A races. B races get a 1-week Pre-Race Taper before their Race Week, with depth governed by your existing taper profile setting (aggressive / standard / conservative) — same Mujika exponential curve as A races, just over a 14-day window instead of 21. Net effect for an athlete with multiple B races leading into an A goal: the CTL build into the A goal is preserved instead of being eroded by repeated multi-week tapers.
  • Improved: Race week now runs a single deterministic day-by-day protocol that A and B races share. A races engage at D-7 (last key session → moderate endurance → easy recovery × 2 → rest × 2 → openers → race day). B races engage at D-4 with identical D-4 to D-0 prescriptions — same two rest days at D-3/D-2, same openers at D-1. The only difference between A and B at this layer is the window length, depth comes from the taper profile setting. Rest days and race day itself are excluded from the dayPlan upstream, so the cron generates and uploads nothing on those dates — clean rest. C events are excluded from the protocol entirely (trained through as before). Replaces several inline pre-race branches in the workout selector with a single source of truth, so what the dashboard, daily cron, TrainNow, and Coach+ all show for a given race-week day is consistent.
  • Improved: HRV dips and disrupted sleep during race-week taper are now framed as expected ("taper tantrums") on the dashboard instead of triggering an alarm-style readiness message the day before a race. On A-race protocol rest days (D-3 / D-2) the dashboard returns a positive "rest per protocol — your fitness is banked" message regardless of single-day wellness fluctuations; on easy days (D-5 / D-4 / D-1) poor recovery or sleep is acknowledged but contextualized as part of the taper response rather than a reason to back off. The underlying signals are still recorded and surfaced in detail views.
  • Fixed: The race-week protocol now actually engages on the dashboard, daily briefing, and Coach+ chat for races more than 1 day out. Previously the daily cron only flagged "tomorrow has a race" so anything from D-2 onwards fell through to the generic phase-based selection — meaning the new A-race D-7 last-key-session and the B-race D-4 / D-3 / D-2 prescriptions never reached production. The cron now scans 7 days ahead and propagates the nearest hard workout to the cache that the dashboard, signals pipeline, and chat all read from.
  • Fixed: The weekly plan no longer jumps straight back to a full Build week as soon as a SICK / INJURED marker drops out of the previous week. Recovery from illness takes longer than seven days, but the planner only looked one week back — so an athlete who was sick three weeks ago could come off two reduced weeks and immediately get hit with a full 1170 TSS Build week, often pushing them straight into TSB -30+ territory the system would then warn about after the fact. The planner now scans the last three weeks for SICK / INJURED events and ramps the next Build weeks back progressively: ~55% target the week immediately after illness (unchanged), ~75% the second week, ~88% the third week, full target from week four. The intermediate weeks are labelled "Post-Illness Build" so it is clear in the calendar why the targets are lower than your fitness alone would suggest.

Friday, May 1, 2026

  • New: IntervalCoach 1.7 for iPhone & iPad is now in the App Store. Major release that brings the full webapp experience to iOS — Apple Health workout sync (with per-sport opt-in) so your training flows automatically into Intervals.icu, send-to-Apple-Watch for any planned workout, a brand-new native Analytics screen (fitness trend, eFTP history with projection plume, power profile radar, critical speed, wellness, training-load distribution, peer benchmarks for Max — tap any chart to read the exact value at a date), Calendar with a month-grid view and sport-colored dots that lets you move/delete workouts in-app instead of bouncing to Intervals.icu, AI-generated race pace plans on A/B/C events, agent Decisions log so you can see what your coach decided and why, Coach+ chat polish with richer signal cards and a tool-approval flow for plan changes, public profile sharing (intervalcoach.app/p/your-handle), full localization to 12 languages, and a top-to-bottom Settings rewrite with native screens for everything (Goals, Notifications, Training, Integrations, Coach Settings for Max, Mobile Sessions, Custom Goal templates, GoalCtlWizard, CoachingMemory, Beta flags, search, profile bio). Plus countless polish, accessibility fixes, and faster startup.
  • Fixed: Your FTP test protocol preference now actually drives which structured test workout the planner generates, and the 20-minute test is now ridable in ERG mode without short-circuiting itself. Previously the choice in Settings was used only for the platform-specific instructions in the workout description — the workout itself was always a ramp-shaped one. So if you picked "20-minute test", you still got a ramp-test workout. The planner now reads your preference: "20-minute test" produces the 20-minute FTP test generator (VO2 blowout → recovery → 20-min time trial), while "ramp", "Zwift", "MyWhoosh" and "custom" produce the progressive ramp generator. The 20-minute time trial is now emitted as a Zwift FreeRide step, which means your trainer drops out of ERG for that segment so you can give a real all-out 20-min effort and Intervals.icu can detect a higher FTP from your actual best power. Without that step, ERG would have held you at the prescribed wattage and the test could never have discovered an improvement.

Thursday, April 30, 2026

  • Fixed: Approving (or rejecting) a Coach+ tool action no longer counts against your monthly chat-message budget, and pending approvals now go through even if you have hit your cap. The generating turn was already charged — re-charging on confirmation was double-billing, and worse, once the cap was reached you would tap Approve and the action would silently fail to commit because the chat call needed to refuse a "new" message. Approve / Reject is now treated as a continuation of the original turn: free, and always allowed to finish.
  • Fixed: Stretching, yoga, e-bike commutes, and weight-training sessions no longer count as "consecutive training days" in the readiness engine. The signal that warns about needing a rest day used to count any activity on a day as a training day, even when the activity carried no power/HR data we could classify as endurance training. So a Sun hard ride → Mon yoga + e-bike commute → Tue ride pattern got read as a 3-consecutive-day streak when in reality there was a real rest day on Monday — and Coach+ pushed back on training requests on the strength of that. Activities without intensity-factor data (which is how Strava-synced e-bike rides, yoga, stretching, and weight training all show up) no longer extend the streak.
  • Fixed: Subscription card no longer shows the wrong "Expires on" date for athletes whose subscription has a fixed cancellation date set in Stripe. If you switched between yearly and monthly billing and Stripe locked in a specific cancellation date to honour the original commitment, the settings page used to show the next monthly invoice as the expiry — even when your subscription would actually keep renewing for many more months. The card now reads the real cancellation timestamp from Stripe and displays that instead.
  • Fixed: Daily Outlook no longer fabricates dramatic reductions ("reduced to 50% TSS, max Z3") on days where the readiness engine flagged a tiny adjustment that didn't pass the adaptation threshold. The system was correctly leaving the workout unchanged on the calendar, but the AI narrative was reading the "Recommendation: MODIFY" header from the underlying decision and amplifying it into a confident prescription that contradicted what was actually scheduled. The prompt now uses a deliberately minimal "execution context only" framing in that case — the active signals are still listed so the coaching note can reference them, but there's no MODIFY header, no TSS percentage, and an explicit rule banning percentage / cap / reduction phrasing in the output. The outlook stays consistent with the calendar.
  • Fixed: Turning off "Daily Adaptation" no longer stops your workouts from getting pushed to your Intervals.icu calendar. The setting is supposed to control only the readiness-driven swap step (changing today's planned workout based on HRV / fatigue / wellness), but the morning cron was treating it as "skip the entire pipeline" — so athletes who explicitly wanted their plan-as-designed without adaptation got an empty calendar instead. The cron now runs as long as your weekly plan is enabled, generates the planned workout, and pushes it to Intervals.icu. The adaptation step is bypassed when you've turned it off, so the workout you get is the one your plan called for, not a reduced or capped version.
  • Fixed: Multi-day holiday/vacation events on the Training Plan timeline no longer show up in the week after they actually end. A vacation that runs through Sunday correctly ends there — the next week starts fresh, no leftover holiday icon. Intervals.icu stores the holiday's end as the moment the next day begins, and the timeline's week-grouping was treating that boundary as if the holiday extended into the following week.
  • Fixed: Coach+ no longer loops trying (and failing) to make a day a rest day. Asking the coach to "make Monday a rest day" used to result in the AI explaining a system limitation and asking how many minutes you wanted Monday set to — because the chat-side schema required durationMinutes ≥ 30 even when the day was being disabled. The schema now treats durationMinutes as optional, and the tool preserves your existing duration (or defaults to 60min) when it's not supplied. Telling the coach to rest a day just works.
  • Fixed: Coach+ no longer recommends a "verplichte rustdag" (mandatory rest day) on days where the dashboard already shows an adapted workout for you. When a critical recovery signal fires (e.g. sympathetic dominance from suppressed HRV plus low HRV-CV), the daily pipeline often softens it into a low-TSS recovery ride that stays on the calendar — rather than deleting today entirely. Coach+ used to read the raw signal and tell you to skip everything, while the dashboard, daily briefing, and calendar were all describing the adapted workout. Coach+ now sees today's actual planned workout (after adaptation) as the source of truth and describes that instead, so all three surfaces agree on what today is. If the calendar genuinely has nothing scheduled, Coach+ still proposes rest like before.
  • Fixed: A short commute or warm-up ride no longer wipes the day's scheduled workout from the dashboard. The calendar used to treat any completed activity as proof that today's session was done, so a 25-minute morning commute uploading to Intervals.icu would make a 2.5-hour Z2 ride disappear from view. Today's planned workouts now only get hidden when a completed activity actually fulfilled them — sport category, duration, AND TSS all have to roughly match. Commutes (different intensity) and coffee rides (low TSS for a planned threshold session) leave the planned workout visible, so commuter-athletes can complete the prescribed session afterwards as intended.
  • Fixed: Athletes without a connected wearable no longer get a falsely confident "Continue training as planned. Recovery indicators look good." When the system has no HRV, resting heart rate, or sleep history to analyse — and no recent workouts flagging fatigue either — it now reports the recovery state honestly as "unknown" with a prompt to connect Apple Health or Whoop to enable recovery tracking. Athletes with even a sliver of wellness data, or with workout patterns indicating fatigue, continue to get the existing best-effort assessment.
  • Fixed: Multi-session training days no longer silently lose their endurance session when the weekly plan trims for spacing. If you had Strength + Run on the same day (e.g. Saturday) plus single sessions on four other days, the planner had 5 endurance sessions to fit into 4 slots and would remove Saturday because doing so produced the cleanest "no consecutive days" pattern on paper. The strength scheduler then booked Saturday separately, leaving you with strength but no run — exactly the opposite of what you configured. The trim heuristic now treats days with a dedicated strength slot as still-training days for the spacing calculation, so it picks an endurance-only day to drop instead and your planned double session survives.
  • Fixed: Daily Outlook on the dashboard no longer stays frozen on pre-event content after you log something on your Intervals.icu calendar (e.g. a sick day, a holiday, a moved workout). The webhook that runs when your calendar changes was clearing the lists of workouts and goals, but not the cached "today's coaching narrative" — so the left-side outlook would still tell you "you're in great shape, proceed with both workouts" while the right-side card already showed "Currently sick · day 1". Adding the readiness narrative to the same invalidation list closes the gap and the two cards stay in sync.
  • Fixed: "Synced X ago" on the dashboard now reflects the most recent fitness/wellness refresh instead of getting stuck at the previous day's timestamp. The dashboard fetches data in two passes — fast vitals first, then the AI-written readiness narrative — and the timestamp pill was including the narrative's cache age in its calculation. But that narrative is regenerated by the second pass, after the first pass has already returned, so the timestamp would always reach back to whenever the previous narrative was generated. Result: a manual refresh would re-fetch everything but the pill would still claim "Synced 7h ago". The pill now reflects the freshness of fitness + wellness only, both of which actually move on a refresh.
  • Fixed: Workout chart on event detail no longer collapses to a flat 50% bar for Run workouts with fractional pace targets. Pace systems like Tinman, McMillan and Pfitzinger express threshold-relative targets to one or two decimal places (e.g. "98.5% Pace", "65.25-70.5% Pace"), and the chart parser was integer-only — every decimal target fell through to a hardcoded 50% fallback. With the dynamic Y-axis introduced earlier this month, that fallback collapsed every interval into a single flat line, hiding the real workout structure. The parser now accepts decimals everywhere a percentage is expected, and the chart renders the prescribed steps faithfully.
  • Fixed: Workout chart Y-axis now labels its 100% reference line correctly per sport. Run workouts were previously labelled "CSS" (Critical Swim Speed) — borrowed from the Swim path because runners and swimmers both train against pace. Run charts now show "Threshold", swim charts keep "CSS", cycling charts keep "FTP". Surfaced together with the decimal-pace fix above, since both bugs hit the same Run-pace workouts.
  • Fixed: Phase Roadmap on the Training Plan page no longer shows a one-week Base island sandwiched between two Build segments. The current week was projected through hysteresis-aware phase logic (which can hold a phase back if you are not yet fitness-ready to advance) while past and future weeks used pure date-based projection. When the date-based timeline had already moved on to Build but the hysteresis was still saying Base, the result was a Build → Base → Build sawtooth that read as a planning glitch. The hysteresis still slows phase advancement when it should, but it can no longer roll the current week behind a phase that an earlier week has already finalised. Multi-race plans are unaffected: weeks immediately following a Race Week still honour the override, so post-race recovery / rebuild structures (e.g. Race Week → Build → Peak → next race) keep working correctly.
  • Fixed: HR-based workouts that crossed two heart-rate zones were silently collapsing to the upper zone only. The workout writer was emitting ranges like "Z1 HR - Z2 HR", which Intervals.icu reads as just the trailing "Z2 HR" — so an "Easy Run" prescribed as Z1-Z2 came across as Z2 throughout, and the chart confirmed the lower bound was being dropped. Range output now uses the combined "Z1-Z2 HR" form (single HR suffix), and Intervals.icu honours both ends of the range. Affects all HR-mode running workouts and HR-mode cycling workouts (the path used by riders without a power meter).
  • Fixed: Race week now includes an opener intensity session for athletes who train 2-3 times per week, even when the race itself lands on one of those training days. Previously the planner produced race weeks with only easy sessions because the math collapsed — if the race ate one of your training days, the "keep at least one endurance day" rule then zeroed out the intensity slot, and the opener floor that protects peak and build weeks didn't cover race week. So a 2-session/week athlete racing on Saturday could end up with just a Tuesday endurance ride for what was meant to be race week. The opener floor now applies to race week as well, with the endurance-day requirement relaxed to one (not two) since low-session athletes only have one training day left after the race day is excluded.
  • Fixed: Peak week TSS targets for high-fitness athletes with limited training hours no longer come out unreachable. If your CTL implied ~875 TSS/week maintenance but your schedule only allows ~4 hours/week, the periodization layer was producing a peak target near 830 TSS — math the workout planner then truncated to ~90 TSS, leaving the peak week looking like a single Wednesday session. The availability cap (hours × TSS-per-hour) now activates by default whenever planned weekly hours are known, even when the calling code omits the explicit TSS-per-hour value, so peak targets stay within what you can actually achieve in the time you have.

Wednesday, April 29, 2026

  • Fixed: Coach+ chat could go silent after running tools — you'd send a message, see the tool cards light up green, and never get a written reply explaining what happened. The chat agent now bumps Gemini's reasoning budget to "low" so it has room to plan a coherent text+tool response, the system prompt has an explicit top-level rule that every reply must contain text (tool calls alone are invisible to you), and on multi-step replies the runtime now forces a text-only follow-up step whenever a previous step emitted tools without text. The pending-approval card already showed which action was queued; you should now also see a sentence telling you what the coach is about to do before the Approve / Reject buttons appear.
  • Improved: Coach+ now pushes back on workout requests that conflict with your adaptation status, instead of silently building whatever you ask for. If today is flagged for rest, capped at Z2, or running a TSS multiplier below 1.0, and you ask for a higher-intensity or higher-load workout, the coach now names the active signal driving that constraint (e.g. "your HRV has been suppressed 3 days running" or "low recovery from Whoop") and proposes an alternative within the cap before generating anything. You can still override — just confirm and the coach will build what you originally asked for. When there are no active signals or only informational ones, it generates immediately like before. Same severity tiers the dashboard and daily email already use, so the coach stays consistent with the rest of the app.
  • Fixed: Coach+ could promise an interval session in text but generate an endurance ride in your calendar — because the model wrote "Z3-intervaltraining" or "blokken" but skipped the `workoutType` argument when calling the workout-generation tool, which silently defaulted to endurance. The chat agent now has an explicit rule that the workoutType passed to the tool must match what the coach promised in text, with mappings for Dutch terms like "blokken" → sweet_spot/threshold, "drempel" → threshold, "duurrit" → endurance, "herstelrit" → recovery.
  • Fixed: Coach+ could leave the original workout on your calendar when you asked it to swap a session to a different day. If you said "instead of Friday I want to train on Thursday" / "ipv vrijdag wil ik op donderdag", the coach would add the Thursday workout but forget to delete the Friday one — leaving you with two workouts when you only asked for one. Cross-day swaps now run as a single atomic tool call (one approval card, one tap) that clears workouts on both the source and target dates before adding the new session. If the swap is a pure move (same workout, different day), the coach uses moveWorkout instead.

Tuesday, April 28, 2026

  • Fixed: Workout rotation now enforces real variety for athletes who train 2-3x/week. Previously the recency penalty decayed on calendar days alone, so the same workout (e.g. "Sweet Spot Blokken") could come back roughly every two weeks for low-frequency athletes — 14 days carried only a small penalty, and the candidate pool for a constrained 60-min intensity slot was small enough that the same choice won again. The penalty now also counts how many actual training sessions sit between two occurrences of the same workout, and takes the stronger of the two scores. For a 2x/week athlete that means 1 session ago = max penalty, 3 sessions ago = strong penalty, ~30 sessions before the workout becomes "free" to repeat — translating to roughly 15 weeks of distinct workouts before any one returns. For a 3x/week athlete that lands at ~10 weeks, and for 5x/week at ~6 weeks. The day curve was also widened so the same workout carries a nudge against repeating through ~2 months. The activity lookback was bumped to 90 days so the full curve has data to act on. High-frequency users (5x/week+) see roughly the same behavior at the front end of the curve they had before, since their day-based and session-based scores already aligned for the first 1-2 weeks.

Monday, April 27, 2026

  • Fixed: HealthKit sync from iOS no longer logs a spurious "field rejection" each time Apple reports a body-fat, VO₂ max, weight, HRR, HRV, resting heart rate, respiratory rate, SpO₂, or wrist-temperature value of 0. Apple HealthKit uses 0 as the "no measurement on file" sentinel for those quantity types, so an athlete who has never entered a body-fat percentage was getting a soft-rejection on every sync; the rest of the payload still landed, but the noise drowned out genuine validation issues. Zeros on those fields are now treated as "not provided" and silently skipped — sub-floor non-zero values (e.g. an obviously broken bodyFat=1.5) still surface so real unit/data bugs don't hide. Sleep-phase fields where 0 is a legitimate reading (no REM detected, etc.) are unaffected.
  • Fixed: Swim workouts no longer show "Rest 25-50mtr 65% pace" between hard intervals. That output read as 25-50m of easy swimming during recovery, which contradicted the prescription — VO2max, threshold, pacing, and pull sets all want the swimmer to grab the wall and stop, not keep swimming. Rest steps in the main set now render as time-based "Rest 30s", so Intervals.icu and Zwift treat them as true wall rest. Affects all four VO2max generators plus threshold/CSS, pacing, pull, endurance, broken-set, tempo, mixed, and kick workouts on TrainNow and the daily cron.
  • Fixed: AI-generated workout titles can no longer disagree with the planned workout type. A swim slot scheduled as VO2max could come back titled "Soglia" (Italian for threshold) or "Threshold Repeats" — the lightweight naming model would latch onto a recovery interval at sub-CSS pace and call the whole session threshold. The naming step now receives the catalog-assigned energy system as context, and validation rejects titles whose intensity tier (in any of the 10 supported languages) contradicts the planned stimulus, falling back to the catalog name when that happens. So a VO2max session is titled VO2max — in every locale.
  • Fixed: Daily Outlook and Today's Plan no longer disagree in the first day or two of a new weekly plan. When wellness signals warranted a material reduction (e.g. "reduce 25%, cap Z3" from HRV suppression or chronic-fatigue risk), the outlook copy was rewritten but the calendar workout was left at its original TSS because a "fresh plan" guard (≤2 days old) blocked adaptation. Athletes saw the outlook saying to back off while the workout below still showed the full prescription — and there was no reduced workout to actually open. That guard was put in place to filter out day-to-day TSB noise on a brand-new plan, but the signals layer now does that filtering on its own (single-day HRV / RHR / sleep / recovery dips stay at "monitor" until they persist). With debouncing in the right place, the freshness carve-out is gone entirely — the same TSB / recovery / signal thresholds apply on day 1 as on day 5, so the calendar always matches what the outlook is asking for.
  • Fixed: Daily Outlook no longer says "skip today's workout entirely (TSS reduced to 0%)" while the calendar still shows the original workout untouched. The morning cron pipeline already deletes the scheduled workout when readiness comes back as "skip"; but if signals shift to skip *after* the cron ran (a fresh wellness reading, an updated Whoop strain, etc.), the dashboard re-evaluates and surfaces the rest-day recommendation while the calendar still holds the workout the cron generated. The outlook now detects that mismatch (skip recommended + a non-recovery workout still scheduled for today) and writes honest copy: it acknowledges the rest-day signal AND that the workout is still on the calendar, instead of asserting a deletion that didn't happen.

Sunday, April 26, 2026

  • Improved: Coach+ chat now runs on Google Gemini 3.1 Flash Lite Preview. Faster responses for multi-turn conversations and lower per-message cost than the previous 2.5 Flash model, with the same tool set (workout generation, schedule changes, training status, etc.) available to all tiers.
  • Improved: A single off morning on Whoop recovery (52-66% / yellow zone) no longer caps today's workout. Last week's update extended this "monitor, don't act" treatment to single-night HRV / RHR / sleep dips; this week the same principle now applies to a one-morning yellow recovery, single-overnight low SpO2, single-night low deep sleep, single-workout slow heart-rate recovery, and one-morning elevated respiratory rate vs personal baseline. The dashboard still surfaces all of these as observations with a "Monitor" chip — the scheduler only acts when the pattern persists 2+ consecutive days, exactly mirroring how HRV/RHR sustained checks already work. Critical safety nets (recovery red, SpO2 <92%, skin temp >1°C above baseline) stay actionable from day one.
  • Fixed: Health card on the dashboard no longer shows mismatched colors. Previously a category pill (e.g. Bio) could light up orange while the warning card directly below was rendered in soft green with a "Monitor" chip, and the "2 warnings" badge in the header counted monitor-only observations as warnings. The pill aggregation, the count badge, and the category status in the detail sheet now all exclude monitor-tier signals — so a category whose only finding is a single-day observation reads as neutral, the badge accurately counts only what actually changed today's plan, and a new "X to monitor" status replaces the misleading green checkmark when there are observations worth noting but nothing to act on.
  • Improved: Health detail sheet now shows every metric — the Sleep section was dropping deep sleep, sleep debt, sleep disturbances, and sleep efficiency entirely whenever they were within range, and the Recovery section was hiding heart-rate recovery and VO₂ Max under the same conditions. Each of those detectors previously only emitted when something was off; they now also emit an info-level "OK" reading when the metric is normal, so the category sections show all the data instead of silently omitting half of it. Same treatment applied to Load metrics: ramp rate, week-over-week volume change, and Whoop day strain now show their current value as an info row when within range, alongside the existing within-range rows for chronic fatigue, TSB, monotony, ACWR, etc. Translations added across all 12 languages.

Saturday, April 25, 2026

  • New: Five new Base-phase workout templates that package a small intensity stimulus inside a Z2 endurance ride/run, so a busy athlete with limited weekly hours can hit VO2max, tempo, neuromuscular, or strength touches inside an aerobic volume day instead of needing a separate pure-intensity slot. The new templates: Endurance + Microbursts (Z2 wrapping one Rønnestad 30/15s VO2max set), Endurance + Tempo Pushes (Z2 with 4-5 short tempo blocks distributed through the ride), Endurance + Alt VO2max (Z2 with alternating-power VO2max blocks), Endurance + Strength Blocks (Z2 with low-cadence Z3 torque blocks paired with short threshold finishes — cycling only), and Endurance + Sprints (Z2 with 4-6 short 10-second neuromuscular sprints for sharpening). Recency-aware selection now rotates these alongside Endurance, Sweet Spot, and Fartlek so Base weeks stop cycling through the same three workouts.
  • Fixed: "Very high previous day strain" signal renamed to "Very high day strain". The signal reads today's Whoop strain — not yesterday's — so the title was misleading athletes into thinking it referred to the previous day. Updated across all 13 supported languages.
  • Improved: Respiratory rate is now compared against your personal 30-day baseline, matching what Whoop does. The old fixed 18 breaths/min floor never fired for athletes with naturally low resting RR (~13 rpm typical), so a clear personal elevation showed as "normal" in IntervalCoach while Whoop flagged it. The signal now also fires when today is ≥1.5 SD above your own baseline (after ~14 days of data), and the "normal" message includes your 30-day average for context.
  • Fixed: Daily Briefing (iOS) and morning email no longer show yesterday's Whoop recovery percentage when today's reading is already available. The webhook handler was fetching `/recovery?limit=1` and blindly using `records[0]`, which can be yesterday's most-recently-scored value when today's recovery hasn't propagated yet — and the resulting wrong value got written into today's slot in the unified wellness store, where it stuck because a later webhook with the real value was early-returned by an "already ran today" guard. The webhook now fetches the specific recovery the `recovery.updated` event fired for (by sleep UUID), writes it to the date the recovery is for in the athlete's timezone, and refreshes the briefing snapshot even when the daily workout already ran. The morning cron path also now refuses to write a Whoop recovery into a date slot that doesn't match the recovery's own date.
  • Improved: A single-day HRV dip or resting-heart-rate bump no longer changes today's workout on its own. The dashboard still surfaces the observation so you see what's happening, but the scheduler only acts on the pattern — HRV suppressed 2+ consecutive days, or RHR elevated 2+ consecutive days. The same applies to one bad night of sleep, single-day disturbances/efficiency dips, single-day skin-temperature or respiratory-rate elevations, and self-reported fatigue/stress/mood/motivation entries: surface as observations only, no plan change unless the pattern corroborates with a sustained metric. The dashboard Health card and Coach+ now show a small "Monitor" chip next to these so you can tell at a glance what was just an observation vs what actually drove today's plan. An experienced coach's framing: one bad reading is a flag, a trend is a diagnosis.
  • Fixed: Workouts now keep generating after your A-race date passes. Previously, once your goal date was in the past the planner kept trying to project weeks "to the goal" — which only produced past weeks — and the day plan stayed stuck behind today, so no new workouts rolled out. Expired goals now route through the maintenance plan: 4 weeks of forward periodised training that holds your current CTL, exactly the same plan you'd get if you had no goal set. Set a new A/B race in Intervals.icu to switch back into a goal-driven build.
  • Fixed: Race Week and pre-race Taper TSS targets now actually apply for intermediate A/B races and short-plan tapers. Two related symptoms athletes were hitting: (1) for plans with the goal as the only A-race, the Race Week itself sometimes landed at ~70% of Peak instead of the intended ~50%, because the Mujika taper curve evaluated at the week midpoint produces ~55-60% but the calendar-event-driven path (which uses a hard 0.5×base ceiling) wasn't reachable when the goal date had no calendar entry — Race Week now applies the same 0.5×base ceiling on both paths; (2) when a tune-up A/B race sat 3-4 weeks before the goal, the weeks immediately before the intermediate were still classified as Peak (because phase derivation was goal-relative only), so athletes arrived at the intermediate race without any taper. Phase derivation now anchors to the *nearest upcoming A/B race* per week, so a real Peak → Taper → Race-Week ramp lands ahead of every A/B race on the calendar, not only the goal.
  • Added: Health detail sheet now has a "Biometrics" section with tiles for resting HR, HRV, sleep, wrist temperature, SpO2, and respiratory rate. Each tile shows a baseline gauge and a Normal / Higher / Lower status pill, so you see both today's number and where it sits relative to your personal 30-day baseline at a glance. Wrist temp and SpO2 in particular are now first-class instead of buried in narrative signals.
  • Fixed: Coach+ memories like "no intensity on weekends" now actually change which days get threshold or VO2 work. Previously the planner picked intensity days from your training history alone — so even after you asked the coach to keep Saturday easy, Saturday could still come back as a Threshold session the following week. Day-of-week preferences from your custom instructions and Coach+ memories now feed directly into day selection (hard constraint for "no intensity on X", soft preference for "X is my hard day"). The coach also confirms by name which days it set as endurance-only when you ask — so you can see what took effect rather than getting a vague "I'll remember."
  • Fixed: 20 signal-detector strings — chronic sympathetic dominance, low motivation, menstrual period, AI training-load advice (progressive / recovery / reduce), recovery week recommended, fitness projection behind, hard session tomorrow / fatigued today, single-day HRV / RHR warnings, mid-week check (catch up / lighter session), elevated and very high ramp rate, training gap (extended / moderate), large weekly volume jump and volume increase, optimal training load progression — were shipping in English on the dashboard for non-English users. The keys were copied to all 11 non-English locales when the detectors landed but the values were never translated, and `validate:i18n` only checked key parity, not value-language parity. All 17 keys × 11 locales × 2 fields are now translated, and the validator gained an identical-to-English heuristic that fails CI for `signals.json` going forward (other namespaces still produce warnings until their translation backlog is paid down).
  • New: eFTP projection on the Analytics page. Your eFTP history chart now continues into the future as a dashed line with a widening "weather-plume" band showing the uncertainty cone — projected forward along your planned CTL trajectory using a per-athlete regression fit to up to a year of weekly snapshots. Requires at least 8 weeks of data before it shows (otherwise the fit is too noisy to trust). Tooltip on future dates includes the projected value and its range; the band widens with horizon to honestly reflect growing uncertainty the further out you look. It's directional guidance, not a promise — actual FTP gains also depend on training specificity, not just volume.
  • Fixed: Weekly performance snapshots and historical eFTP fallback now read from the same power-curve source the dashboard uses, so athletes whose eFTP lives in per-sport mmp_model.ftp (instead of as SET_EFTP fitness-model events) finally get a real eFTP recorded each week. Previously every snapshot for those athletes had eftp:null, which silently hid the new eFTP projection plume on Analytics and left dashboard-email/badge fitness numbers inconsistent with the dashboard.

Friday, April 24, 2026

  • Fixed: CTL Projection graph no longer spikes upward in weeks that contain a race event. The week's planned TSS already includes the race's own training load (e.g. a 1000-TSS event in a 1000-TSS week), and the projection was spreading that race stress evenly across all 7 days — so a single race was inflating CTL for the entire surrounding week and the curve ran away to unrealistic values in the approach to the goal. The race's icu_training_load is now subtracted before distributing the week's remaining training budget across the non-race days.
  • Fixed: "Mid-week check recommends lighter session" no longer fires on weeks with barely any volume. The detector that produced that signal was keyword-matching the upstream planning prompt — and because the prompt template itself contained the words "recovery" / "reduce", every athlete got a reduce recommendation every Wed–Sat regardless of their actual state. It now branches on numeric triggers (weekly TSS deficit + wellness + TSB), so athletes who are behind on weekly load with normal recovery get a catchup signal instead of a false "back off" message.
  • Fixed: Intermediate A-races now get the same two-day post-race recovery window the pre-race taper already has. Previously only the day immediately after an A/B race was protected, so a race on Friday could still be followed by a Threshold long run on Sunday. Now both D+1 and D+2 after any A/B race are treated as recovery — no threshold, VO2max, or sweet-spot on either day — which matches the existing symmetric two-day pre-race taper and helps athletes with back-to-back A-races on a ~9-day cadence.
  • Fixed: A calendar NOTE with Intervals.icu availability set to UNAVAILABLE or LIMITED now always blocks/limits training on that day, regardless of the note's name. Previously the planner only recognised NOTEs whose name matched a hardcoded keyword list (holiday, vacation, trip, etc.), so a note called "Meeting" or "Flight" with availability explicitly set to UNAVAILABLE was silently ignored and a workout was scheduled on top of it. The structured availability field is the signal we promise to honour in the support docs, and it now wins regardless of name.
  • Fixed: Activity heatmap no longer shows MountainBike, Gravel, EBike, and TrailRun activities as "Mixed" (orange). The heatmap sport classifier only recognised the base Ride/Run types and was bucketing every other cycling/running subtype into a generic "Other" category, so athletes who ride almost exclusively MTB or gravel saw their entire 365-day calendar rendered as "Mixed" instead of Cycling blue. MountainBikeRide, EMountainBikeRide, GravelRide, EBikeRide, Velomobile, Handcycle now count as Cycling and TrailRun counts as Running — consistent with how the rest of the app already classifies those types.
  • Fixed: iOS Daily Briefing and Dashboard Daily Outlook no longer disagree about HRV-driven adjustments. The dashboard was surfacing messages like "Proceed with Over-Under Intervals today but cap intensity at Z3 and reduce overall effort slightly due to HRV signals", while the Daily Briefing for the same morning showed a generic coaching note about Over-Under intervals being "a great opportunity to build on threshold fitness" — no mention of the HRV cap. Both narratives are now driven by the same readiness-decision context, so athletes who open the Daily Briefing on iOS see the same signal-aware guidance the web shows.
  • Fixed: Deep-sleep-deficit signal no longer fires every single night for athletes whose natural deep-sleep range sits below 1.5h. The signal previously used a fixed 1.5h global threshold and flagged athletes with a 0.9–1.1h personal norm as deficient every night, which kept their workouts permanently capped at reduced intensity. It now compares today's deep sleep against the athlete's own 30-day baseline and only fires when today is meaningfully below personal norm (≥1.5 standard deviations). Suppressed entirely for the first ~2 weeks while the baseline is still being collected — consistent with the HRV and resting-HR baseline approach.

Thursday, April 23, 2026

  • New: Users now get a confirmation email the moment a paid subscription drops (Pro → Free, Max → Pro, or Max → Free). Previously there was radio silence for 7–14 days until the win-back email fired — now there's an immediate acknowledgment with a clear rundown of what changes and a one-tap reactivation link. Covers Stripe cancellations, trial expiry, and App Store cancellations through the same hook.
  • Fixed: Workout Profile chart on run activity detail modals no longer renders as a solid block of Z6 red that bleeds past its container. The chart derived FTP from normalized power ÷ intensity factor, but treated the intensity factor as a decimal (0-1) when Intervals.icu returns it as a percentage (0-100). For a typical run that gave an FTP of ~3W, which made every interval read as 6000%+ of FTP and colour-coded everything as anaerobic. FTP is now derived correctly for both the percentage and decimal forms, so run charts paint the right zones.

Wednesday, April 22, 2026

  • Fixed: Morning workout email no longer silently shows "60 min" when the actual workout is longer. A hardcoded fallback in the email builder was kicking in whenever the upstream duration didn't propagate (e.g. a 90-minute endurance ride showing as 60 minutes in the email while the app calendar was correct). The fallback is gone — the email now hides the duration row entirely if it's not available, so the two surfaces can't disagree.
  • Fixed: Apple Watch wrist temperature now actually reaches IntervalCoach. Since the Apple Health integration shipped, every wristTemp reading was silently rejected at the backend — the server was validating the value as a "deviation from baseline" (±5 °C) while Apple's HealthKit actually reports the absolute temperature (30–36 °C during sleep). The range now accepts absolute Celsius values, matching what Apple's API and the Whoop integration have always sent. No action needed on your side; your next overnight sync will populate the field.
  • Fixed: Daily Outlook no longer tells you to "proceed at 90% intensity" on days when your scheduled workout was actually kept unchanged. When signals flagged a mild reduction (e.g. TSS multiplier 0.9 exactly), the adaptation-threshold gate correctly left the planned workout alone, but the outlook copy still described it as being at 90% intensity — implying you should manually dial it back on a workout that was already right-sized. The outlook now only talks about reductions when the system actually applied one, and when adaptation does fire it phrases it declaratively ("we reduced today's TSS to X%") instead of asking you to self-adjust.
  • New (iOS): Apple Health is now a first-class data source in IntervalCoach. HRV, resting heart rate, respiratory rate, blood oxygen, wrist temperature, sleep phases (REM / deep / core), VO₂ Max, heart rate recovery, body weight, body fat, and menstrual phase all flow into the same readiness pipeline Whoop has always driven — so you get recovery-aware coaching with just your Apple Watch, no Whoop strap required. If you have both connected, Whoop stays primary and Apple Health fills the gaps (body weight, body fat, VO₂ Max, heart rate recovery). Everything compatible also mirrors to Intervals.icu so your wellness history there stays complete. Update the IntervalCoach iPhone app from the App Store and toggle Apple Health on in Settings to turn it on.
  • New: Three new signals feed the readiness score. Heart rate recovery slowing vs your 14-day baseline flags sympathetic under-reactivity (a subtle overreaching signal HRV alone can miss). VO₂ Max declining vs your 30-day peak warns early about burnout. Menstrual phase is auto-detected from Apple Health and surfaced as info-level context today — phase-aware signal interpretation (so luteal-phase HRV dips don't trigger false fatigue alarms) is next up on the roadmap.
  • Fixed: Agent Log and Dashboard no longer disagree about daily adaptations. The morning cron was running the signals pipeline with a narrower set of inputs than the dashboard, so the stored Agent Log could say "No adaptation signals detected — training as planned" while the dashboard (running the same pipeline with the full input set) surfaced real warnings like "Mid-week check recommends lighter session". The cron now pre-assembles the complete signals input once via the shared `assembleDetectorInput` helper and feeds it into every downstream step — so the Agent Log, the scheduled workout, the dashboard, Coach+ chat, and push notifications all read from the same daily health assessment, and the scheduled workout is actually adapted when a signal fires.
  • New: Dashboard now detects when today falls inside a multi-day holiday event (vacation, travel, stage break) with training availability set to UNAVAILABLE and surfaces a dedicated "On holiday" context to the iOS app. The iOS app can now render a dedicated holiday card instead of the generic rest-day card when you are on vacation — the two states mean different things (planned time off vs. signal-driven recovery) and shouldn't look identical.

Tuesday, April 21, 2026

  • Improved: JustTrain signals now match the Dashboard. The "Choose workout" step replaces the old warning list with the same Health card you see on the Dashboard — always visible, including the green "all clear" state when nothing is firing, plus category pills for Recovery / Sleep / HRV / Load / Bio. Both surfaces now read from the same source, so what you see on JustTrain and the Dashboard can never disagree about today's state.
  • New: Coach+ chat tool getActiveSignals replaces getTrainingWarnings. The coach now sees the full unified signals report (illness, subjective wellness, HRV stability, monotony, ACWR, load-recovery ratio, durability, AI training-load advice, etc.) plus the actions the rules engine derived from each signal — so it can explain "today's TSS is capped at 70% with a Z3 ceiling because tsb-deep-fatigue fired" instead of just listing warnings.
  • New: Coach+ chat can now answer detailed questions about your analytics — fitness trends, weekly TSS history, eFTP progression, and progressive overload status. Ask "How has my fitness changed in the last 6 months?" or "Am I trending up on FTP?" and the coach will pull the actual numbers instead of guessing. The new analytics summary also covers 7-day and 365-day windows in addition to 30/90.
  • New (Max): Peer benchmark comparison in Coach+ chat. Ask "How do I compare to other riders my age?" or "What's my percentile for 20-min power?" and the coach returns your percentile rank for cycling W/kg (5s, 1min, 5min, 20min, 30min, 60min), CTL, and weekly TSS — filtered by sex and age bracket from the same cohort data shown on the Analytics page.
  • Improved: The deload, ramp-rate, volume-jump, and training-gap checks that previously lived in a parallel "training warnings" system are now first-class signals in the unified pipeline. The dashboard Health card, daily pipeline adaptations, training-plan warnings panel, and Coach+ all read from the same source — your dashboard signals and what the workout selector actually does are now guaranteed to match.
  • Improved: Fatigue thresholds in the signals engine are now sport-aware (Foster 1998). Runners trigger the deep-fatigue signal earlier (TSB < -20) than cyclists (TSB < -30), reflecting the higher RPE running produces at the same training load.
  • Improved: Swimming workouts rebuilt to match expert swim-coach prescriptions. Threshold sessions now use classic CSS 100m repeats with 35s rest (10–20 × 100m) and a new pacing variant alternates 100m Z2 with 200m Z4 with a full 60s rest between pairs — proper recovery to keep each CSS interval clean instead of the old 15s rest that turned threshold work into glycolytic mush. Pull sets are simplified to two clean patterns: 10 × 100m @ Z3 / 10s rest for short sessions, or 2–3 × 400m @ Z3 / 30–40s rest for longer ones (replacing the previous alternating 100/150 patchwork). Endurance sessions gain structure too: long sessions now swim 3–4 × 400m at Z2–Z3 with 30s rest, medium sessions break into 100Z2/200Z3/100Z2 mini-sets with 1min rest, and short sessions keep a continuous steady block. Broken sets, tempo, and mixed-zone workouts also get realistic swim-coach rest durations tuned to rep distance.
  • Improved: Post-workout analysis now sees the back half of long rides. Previously rides with more than 15 intervals (e.g. a 7h BRM 200 with 41 laps) had everything past the first ~2.5 hours summarised as "and 26 more intervals" with no data, making the AI blind to second-half pacing and power fade. The detailed per-interval window now covers the first 30 intervals (enough for essentially every structured workout — 10×5min, 20×1min, 3×20min — to stay fully itemised) and anything beyond that is bucketed by type (WORK / REST) with totals and average power/HR/TSS so the full effort distribution stays visible.
  • Fixed: Over-under / criss-cross threshold workouts no longer collapse to a single short block. Planned 90-minute sessions with 3-4 blocks were being truncated to ~33 minutes because the post-processing pass mistook the inter-block "Recovery" marker for the cooldown. All blocks and the real cooldown now survive.
  • Fixed: No single workout can exceed 60% of the weekly TSS target, even for athletes with very uneven training availability (e.g. one 10-hour day + short weekday sessions). Previously a remainder-distribution pass ignored the cap and could push a long weekend ride to 70-85% of the weekly target, which the judge flagged as an unreasonable load for the athlete's current fitness.
  • Fixed: Edit Workout dialog on the training plan now shows the same TSS as the calendar grid for IC-generated workouts. Previously the dialog re-derived TSS from category × duration defaults (e.g. "recovery × 218 min = 98 TSS") even when the actual workout structure delivered something different (29 TSS), so the dialog and the calendar disagreed for the same session. The dialog now keeps the persisted TSS until you change the category or duration.

Monday, April 20, 2026

  • Fixed: Dashboard card showing weekly High-Intensity Sessions (VO2max / Threshold / Sweet Spot counts) stayed stuck on its loading skeleton after the recent dashboard API refactor. The analytics endpoint computed the data but forgot to include it in the response, so the card never rendered. Same fix restores the Power Profile data block for feature surfaces that use it.

Saturday, April 18, 2026

  • New: Dashboard top section redesigned to match the iOS app. Three activity rings show Readiness, Form, and Week TSS at a glance (with a track marker pointing to where your weekly progress should be by now). Below the rings, a color-accented "Daily Outlook" presents the AI coaching message, today's training recommendation, and any alternative. Today's planned workout continues seamlessly in the same card so the whole "what should I do right now" story reads as one unit.
  • New: Wellness metrics on the dashboard are now four quick-stat tiles (Recovery, Sleep, HRV, Resting HR). Tap any tile to open a full Health Details sheet with every metric, every signal grouped by category, and the reasoning behind today's readiness.
  • New: Always-visible Health card on the dashboard. Shows warning count, category dots (Recovery / Sleep / HRV / Load / Bio) with color-coded status, and inline cards for anything that needs attention — same UX you already had on iOS.
  • New: Mid-week coaching is now bidirectional. The Wed–Sat mid-week check can both back you off (lighter session when fatigued) AND push you forward (upgrade to a harder session when you are behind on the week's TSS target). Reductions always dominate, so being fatigued + behind on TSS still gets you a lighter day.
  • Fixed: Coach+ "adjust/swap/change/replace/modify" requests now actually replace the existing workout instead of silently adding a new one alongside. Previously asking the coach to "swap today's force intervals for an endurance ride" would leave the force intervals on the calendar and add the endurance ride as a second workout, and bulk requests like "replace all weekend structured workouts with long rides" could accumulate 10+ duplicates on a single day. The coach now snapshots existing workouts on the target date before uploading the replacement, then removes them — race events (A/B/C) are never touched.
  • Fixed: Coach+ chat was reporting a nonsensical average speed (e.g. "9.58 km/u" for a 41.7 km / 72 min ride). Intervals.icu returns speed in m/s and the raw number was being passed to the chat model, which then mislabelled it as km/h. Average and max speed are now converted to km/h or mph according to your unit preference before the coach sees them.
  • Fixed: Health sheet in the iOS app and adaptation signals on the web dashboard were showing a truncated set (~18) of signals instead of the full daily health assessment. The dashboard, Coach+ chat, and push-notification endpoints were each building their own thinner signal input and silently skipping the AI-driven detectors (training-load advice, mid-week adaptation, upcoming hard session, fitness projection, consistency, durability). Every surface now shares a single assembler that reads the same daily health assessment the workout agent ran with, so what you see on iOS matches the web dashboard, the Coach+ chat, and today's push notification.
  • Fixed: Training Plan page now shows the same current CTL on the Fitness Projection graph and the info bar below. Previously the graph trajectory used a stored value recorded by the weekly Sunday cron, so when your actual CTL drifted during the week (e.g. the graph showed 79 while the bar said 74), the two appeared to disagree. The projection is now recomputed from today's fresh CTL whenever it has drifted more than one point from the stored value.
  • Fixed: Long endurance rides with TSS ≥ 60 are no longer misclassified as "hard workouts". Planned intensity is now derived from Intensity Factor (IF = √(TSS / (hours × 100))), matching the polarized training model used across the rest of the app. Previously a 2h / 70 TSS endurance ride (IF ≈ 0.59) was flagged the same as a 1h / 95 TSS threshold session (IF ≈ 0.97), causing the daily agent to unnecessarily replace the ride with a lighter workout.
  • Fixed: Daily workout email showed the raw workout type ID (e.g. "enduranceSpinUps") as the title instead of the readable name ("IntervalCoach - Endurance Spin Ups").
  • Fixed: Daily workout email and Agent Log on the /decisions page no longer display raw translation keys such as "reasons.alreadyScheduledToday|IntervalCoach - Duurtraining". Reason strings are now rendered in your language across the email, the decisions UI, and TrainNow.
  • Fixed: Agent Log "load adjustment" entries now only appear when a recovery/fatigue/wellness signal actually drove the reduction. Previously the log would show "Moderate load reduction" with trigger "load" even on fully green days when the reduction was really a scheduling decision (race taper, rest day on the plan, already-scheduled session).
  • Fixed: Dashboard completed-workout card and Today's Plan card now show the correct sport icon for swims, virtual rides, gravel rides, mountain bike rides, e-bike rides, trail runs, and virtual runs. Previously the dashboard fell back to a strength dumbbell for any activity type that wasn't exactly "Ride" or "Run".
  • Fixed: Dashboard wellness tiles no longer truncate their labels (e.g. HERSTEL, SLAAP, RHR) at narrower viewport widths, and the sleep value now stays on a single line (7h35m). The Readiness ring label also scales to fit longer words like "Stabiel" without overflowing the ring.
  • Improved: All state-driven workout adaptations now flow through a single signals → actions pipeline instead of hard-coded branches scattered across workout-selection. Deep fatigue, AI training-load advice (Recovery/Reduce/Build/Aggressive), "hard session tomorrow + fatigued today", mid-week catch-up, and fitness-projection trailing target all emit proper signals with typed action rules — so the Agent Log attributes each adjustment to the specific signal that triggered it.
  • Fixed: Coach+ chat can now explain WHY you're "At Risk" or "Behind Target" for a goal event with concrete numbers. Previously when you asked "what specifically is the problem?" the coach could only guess (peak phase, TSB, recent focus) because the dashboard's readiness status and the specific CTL gap to your target were never passed to the chat model. The coach now has access to your target CTL, projected CTL, the gap between them, and the reason the status was assigned — so it can answer "you're projected at 60 CTL but your target is 72, so you're 12 CTL short" instead of generic coaching speak.
  • Fixed: Remaining Coach+ messages no longer reset to the monthly tier limit every time you reopened the iOS app. The App Store receipt verification the app runs on launch was wiping the monthly chat counter on each call, so after sending a few messages, closing the app, and reopening it, your remaining count jumped back to 20/20. Re-verification of an already-active subscription now leaves the counter untouched; it is only reset on a genuine upgrade (new purchase or tier change).

Friday, April 17, 2026

  • Fixed: Multi-day events (vacations marked unavailable, stage races, multi-day cycling weekends) now appear on every day of their range in the Dashboard upcoming list instead of only the first day with subsequent days showing "Rest day". The web calendar already displayed this correctly.
  • New: Training overview widget on your public profile and analytics page. Shows total TSS and current streak as hero stats, plus workouts, time, distance, active days, peak training hour, and your favorite sport. A GitHub-style heatmap colors each day by your primary sport (cycling blue, running red, swimming teal, rowing violet), with a dot in the corner for multi-sport days. Analytics scopes the widget to your selected time range; your profile shows lifetime. Available in all 12 languages and respects your metric/imperial preference.
  • Fixed: Taper weeks now include only one short intensity session (opener) instead of two. Previously taper weeks scheduled two full threshold/sweetspot sessions, which is too much load in the final 1-3 weeks before an A race. The remaining workouts stay as easy endurance to reduce accumulated fatigue while preserving race-day sharpness.
  • Fixed: Taper weeks no longer concentrate training load on a single long Saturday ride. The per-day TSS cap was tightened from 60% to 40% of the weekly target for taper and pre-race taper weeks, producing a more balanced distribution so one session does not dominate the week.
  • Fixed: Intensity sessions in recovery and taper weeks are now short tempo efforts instead of full threshold workouts. Previously the opener in a 250 TSS recovery week could be a 90 TSS threshold session (over a third of the weekly budget); it now uses the tempo category so the opener stays appropriate to the week's light load.

Thursday, April 16, 2026

  • Fixed: Trail runs, virtual runs, gravel rides, mountain bike rides, and other Intervals.icu activity subtypes now show the correct sport icon on the training plan weekly schedule. Previously anything that wasn't exactly "Run" or "Ride" fell back to a bike icon.
  • Fixed: The AI Coach card no longer shows a generic "Today: Free Training" label alongside a scheduled workout. When a workout is already on your calendar for today, the planned workout IS today's recommendation — the generic type badge is now hidden to avoid the confusing contradiction.
  • New: Universal Links. Tapping an intervalcoach.app link (from Mail, Messages, Safari, etc.) now opens the iOS app directly if you have it installed.
  • Fixed: Progressive Load trend percentages now reconcile with the values shown. Previously the trend could show +97% while the displayed wattages only changed by ~13%, because the trend was secretly computed from a multi-week average (and sometimes TSS). The table now shows the exact aggregates the trend was calculated from.
  • New: Breathing protocol on the workout chart. When your HRV is suppressed or elevated-variable, your cooldown is split into a normal ramp-down plus a dedicated "Breathing Protocol" segment so the box-breathing work is structured into the ride / run / swim itself, not just an email note.
  • New: Protocol row on Today's Plan. If today's workout has a signal-driven adaptation (extended warmup, breathing cooldown, stimulus swap, sleep hygiene), you'll see a compact row of icons describing it without cluttering the dashboard with an extra card.
  • Improved: High training monotony now triggers a swap to an endurance session on top of the load reduction — a genuinely different stimulus, not just a lighter version of the same thing.
  • Improved: Declining aerobic efficiency (durability signal) now swaps today's session for an easy endurance ride so you rebuild the aerobic base instead of continuing the high-intensity pattern that eroded it.
  • Fixed: Agent Log no longer shows a red "Rest" badge for days when the pipeline was actually keeping your planned workout unchanged. The badge now reflects the real readiness assessment (Push / Moderate / Rest), matching what the Dashboard shows. Signals like yellow recovery and sleep shortage now also appear in the log entry for these days.
  • Improved: Daily workout adaptation now uses the full readiness signals engine. Previously only a large TSB drop or red recovery would replace a planned workout; yellow recovery combined with short sleep, HRV instability, or training monotony went unaddressed even when the Dashboard already recommended capping intensity. Now the Dashboard and the actual workout stay in sync.
  • Improved: When signals cap your intensity for the day, the coach now swaps the workout type (e.g. VO2max → Tempo, Threshold → Sweet Spot) instead of only reducing TSS on the same type. This gives you a more appropriate stimulus on recovery-limited days.
  • New: The coach now extends your warmup by 5 minutes when you report high soreness, easing you into the main set to protect sore tissue. The extension is absorbed from the main set so your total workout length stays the same.
  • New: When your HRV is suppressed or HRV variability is elevated, the coach now extends your cooldown by 5 minutes so you can do structured breathing work (box breathing 4-4-4-4) to downshift your nervous system. This was previously only mentioned in the email text — now it is actually part of the workout.
  • New: When recent workouts have felt consistently harder than expected, the coach now swaps today's session for an aerobic endurance ride instead of retrying the same hard stimulus. Previously this signal was purely informational.
  • Improved: Coaching note now includes concrete protocol bullets (🔥 extended warmup, 🌬️ extended cooldown with breathing, 🛌 sleep hygiene) so you see exactly what to do differently today.
  • Fixed: Training plan no longer shows placeholder workouts on past days when a session is skipped. The remaining weekly TSS is now redistributed across the days you still have left to train.
  • Fixed: Warmup and cooldown on cycling recovery rides no longer exceed the intensity of the main set. Previously a recovery ride with a 45-55% FTP main set had a warmup ramping up to 75% and a cooldown starting at 65% — bookends harder than the actual work. Both are now capped within Z1.
  • Fixed: Recovery status on the Train page now uses your HRV and resting-HR baseline when your device doesn't provide a recovery score. Garmin and other users without a recovery % saw "Unknown" even when HRV/RHR were clearly favorable; now you get a Green/Normal/Yellow reading derived from the deviation vs your 30-day baseline.

Wednesday, April 15, 2026

  • New: IntervalCoach is now available as a native iPhone app. Daily briefing with push notifications, Coach+ chat, activity analysis, calendar, dashboard, and post-workout feedback. Download from the App Store: https://apps.apple.com/app/intervalcoach-companion/id6760976369
  • Fixed: Sweet Spot and other interval workouts no longer generate continuous work blocks without recovery when TSS adjustment adds extra intervals. Recovery is now always included between intervals.
  • Fixed: Scheduled workouts are now automatically removed from your calendar when you mark yourself as sick or injured. Previously the sick-day email was sent correctly but planned workouts remained on the calendar.
  • New: Wellness check-in in the daily briefing. Rate your stress and motivation with a single tap. Low motivation triggers coaching adjustments. Menstrual cycle tracking available as an opt-in setting.
  • New: Chronic stress detection. The system now identifies when HRV is both suppressed and unusually stable — a pattern indicating chronic sympathetic dominance that standard metrics miss.
  • New: Recovery recommendations. When stress signals are elevated, your coaching note includes targeted recovery actions like breathing exercises, cooldown protocols, and sleep tips.
  • Improved: Readiness level is now derived directly from your body signals for more consistent and accurate training guidance.
  • New: HRV stability trend in your daily coaching note shows whether your autonomic stability is improving or worsening week-over-week.

Tuesday, April 14, 2026

  • New: Taper aggressiveness setting. Choose how aggressively your training volume drops before a race: Aggressive (~60% reduction, research-optimal), Standard (~45%, default), or Conservative (~25%, minimal). Find it in Settings > Periodization > Advanced.
  • New: Heart rate-based cycling workouts. If you ride outdoors without a power meter, you can now switch cycling workout targets to heart rate zones in Settings > Training. Workouts will use Z1-Z5 HR targets that sync to your Garmin or bike computer. Your HR zones from Intervals.icu are used automatically.
  • Fixed Fitness/Fatigue/Form values showing differently on the Dashboard vs Analytics page. The fitness trend chart now uses the same adjusted values as the Dashboard, which correctly excludes planned workouts that haven't been completed yet.
  • Fixed running best efforts in Analytics showing modeled/predicted times instead of actual recorded times. Short distances (400m, 800m) now show your real race/workout times from Intervals.icu.
  • Fixed post-workout and daily emails not respecting your unit preference. If you switched to Imperial in Settings, the app showed miles correctly but emails still used kilometers. Now fixed for all email types.
  • Coach+ now returns total elapsed time (including stops) when you ask about an activity, not just moving time.
  • New (Beta): Agent Log. See a timeline of every decision the AI coach makes: readiness assessments, workout selections, phase transitions, weekly plans, and post-workout analysis with full reasoning. Enable in Settings > Beta (Pro and Max).

Monday, April 13, 2026

  • Fixed duplicate workouts appearing on the calendar after a plan regeneration. When the weekly plan changed (e.g. different workout type, duration, or sport on a given day), old workouts were not being cleaned up before new ones were created. The planner now removes all existing IntervalCoach workouts before regenerating, so you always see exactly what the current plan prescribes.
  • Fixed threshold progressive and reversed progression workouts generating unrealistically long intervals for long rides. A 3-hour ride was producing 4x37-minute threshold intervals (up to 105% FTP), which is humanly impossible. Intervals are now capped at 20 minutes for cycling and 15 minutes for running, with remaining time filled by endurance work.
  • Fixed post-workout analysis for runs using power zones instead of heart rate zones, which caused easy Z1 HR runs to be classified as threshold. The analysis now respects your running target preference: if you train by pace or HR, it uses heart rate zones for stimulus classification. Athletes who explicitly chose power mode still get power-based analysis.
  • Fixed consecutive training days warning being triggered by low-intensity activities like dog walks and commutes. Activities below IF 0.40 no longer count as training days, so your readiness assessment stays accurate even if you log daily walks. Gym sessions and recovery spins still count.
  • Fixed post-workout analysis using the wrong FTP after an FTP test. When a ride pushed your eFTP higher, the analysis would judge the ride against the new (higher) number instead of the FTP you were actually working against. Now uses your eFTP from before the ride for accurate assessment.
  • New: Unit preference in Settings. Choose between Metric (km, km/h, meters) and Imperial (miles, mph, feet) for how distances, speeds, and elevations are displayed. Go to Settings > Account to switch.
  • Fixed duplicate workouts being created when the plan regeneration ran twice. A concurrency lock now prevents the second run from creating additional workouts.
  • Fixed Coach+ chat using the wrong date in conversations that span multiple days. If you continued a conversation from a few days ago, the coach could think "today" was a past date and take actions on the wrong day. The current date is now always authoritative.
  • Fixed Coach+ chat falsely claiming that marking a day as unavailable would delete your existing workouts. Blackout dates only prevent future scheduling — existing workouts are now offered for separate deletion.
  • Improved Coach+ activity lookup: the chat now uses your most recent activity directly instead of asking you for an activity ID.
  • Fixed pre-race day workouts ignoring the race sport for multi-sport athletes. If you have a Run race on Sunday, the day before now gets a Run opener instead of the regularly scheduled Ride.
  • Fixed planned workouts showing on the calendar for days that have a race event added after the plan was generated. The planner now automatically removes stale placeholder entries when it detects a race on that date.
  • JustTrain now caps workout intensity when you are recovering from injury or illness. If you had a recent SICK/INJURED event, high-intensity options like VO2max intervals are deprioritized and recovery-friendly workouts are promoted.
  • Fixed some workouts missing their cooldown segment. When TSS adjustment added extra intervals that pushed the workout over its target duration, the cooldown could be squeezed out. The trimming logic now properly shrinks filler segments before removing the cooldown.
  • Fixed trail run events (e.g. "Fyri trail", "Alpine Trail") not being recognized as running goals, causing the weekly plan to generate all rides instead of runs for trail runners.
  • Fixed Progressive Load Growth Rate showing extreme values (e.g. -70% instead of ~10%). The comparison now averages up to 4 previous weeks instead of comparing against a single session, smoothing out outlier effects.
  • Trail run workouts now use higher warmup and cooldown zones (Z2 floor instead of Z1). Staying in Z1 is unrealistic on hilly terrain, so warmup and cooldown targets are raised for trail runners.
  • Fixed Progressive Load trend column misalignment on the Analytics page. Added an info tooltip explaining what the card measures.
  • Fixed workout chart looking flat for running and low-intensity workouts. The chart now zooms into the relevant power range instead of always showing 0-150%, making the structure of endurance and running workouts clearly visible.
  • Fixed strength workouts not being recognized as completed. When you logged a "Strength" or "WeightTraining" activity, the dashboard still showed the planned "IntervalCoach - Lower Body Strength" as pending because the matching was too strict. Now matches by sport category instead of exact name.

Sunday, April 12, 2026

  • New: Beta tab in Settings. You can now opt into experimental features like Training Score directly from your settings, without contacting support.
  • New: Efficiency by Workout Type chart on the Analytics page. See how your Efficiency Factor (power per heartbeat) and TSS/hr evolve over time for each training type: endurance, tempo, sweet spot, threshold, and VO2max. Toggle between EF and TSS/hr views.
  • Improved date labels on all analytics charts: dates now show as "Apr 5" instead of "04-05" for better readability.
  • Fixed sick day detection showing "SICK · DAY 1" on the day after your last sick day for athletes in timezones east of UTC (Australia, NZ, East Asia). The daily briefing and dashboard were using UTC instead of your local timezone, which made the sick event look one day longer than it actually was.
  • Fixed Coach+ chat failing to load activity details when you ask about a specific workout ("How was my last ride?"). The chat could find your activities but would show "activity not found" when trying to get the details.

Saturday, April 11, 2026

  • Fixed a long-standing bug where deleting a workout from the Training Plan silently blocked the planner from ever putting anything back in that slot, for up to four weeks. If you had deleted a workout at any point, those dates stayed "empty" even after regenerating, which made plans look sparse and undershoot their weekly TSS targets. Delete now just means delete: the slot returns to being an empty available day and the next regeneration may refill it. To express "I never train this day", toggle the day off in your training schedule.
  • Deleting a workout no longer redistributes its TSS across the remaining entries in the week. The week will honestly undershoot its target instead of inflating the other workouts to compensate.
  • Fixed Recovery weeks producing half-empty plans. The planner was hardcoding a 40% session cut on top of the volume reduction you had already configured, so Recovery weeks ended up with fewer sessions AND less load per session, doubly undershooting the weekly target. Recovery weeks now keep the same number of sessions as Build weeks and let the TSS target drive per-session volume. Your configured recovery reduction setting is now respected end-to-end.

Friday, April 10, 2026

  • Added a confirmation step before upgrading an existing subscription (e.g. Pro → Max) in the settings page and Coach+ upgrade prompts. You now have to explicitly confirm before your card is charged the prorated difference, so an accidental tap on the upgrade button no longer triggers an immediate payment.
  • Added Mobile Sessions to Account settings. You can now see which devices are signed in to the iOS app and revoke all sessions instantly if needed.

Thursday, April 9, 2026

  • Activities on your public profile are now clickable and link to a dedicated activity detail page you can share on social media. Each shared activity shows duration, distance, TSS, power, heart rate, zone distribution, and workout segments — with a rich preview card when pasted on Twitter, Strava forums, or messaging apps.
  • Improved workout completion detection: the dashboard now correctly recognizes when a completed activity (e.g. "Kort-kort" from Strava) is the same as your planned workout (e.g. "Drempel Herhalingen"), even when names differ. Short warmup rides are no longer confused with planned races.

Tuesday, April 7, 2026

  • Added command palette (Cmd+K / Ctrl+K) for quick access to all pages, Coach+ chat, dark mode toggle, and more. Type to search and navigate instantly.

Monday, April 6, 2026

  • Fixed taper weeks not reducing training load before A races. High-volume athletes saw taper weeks with the same TSS as peak weeks because the availability floor was overriding the taper reduction. Taper and Race Week now properly reduce volume.
  • Fixed training plan continuing to build CTL after the target was already reached. Plans now hold at maintenance when the goal CTL is met, instead of ramping toward the availability ceiling.
  • Fixed over-under workouts having both intervals above FTP. The "Under" was at 91% (Sweet Spot) instead of 95% (just below threshold), and the "Over" was at 100% instead of 105% (just above threshold). On top of that, TSS adjustment was scaling both up to 105-110%, completely defeating the purpose. Over-unders now correctly straddle FTP at 95% and 105%, and their intensities are locked so TSS adjustments can't distort them.
  • Fixed duplicate workouts appearing after weekly plan regeneration. When a plan changed the sport assigned to a date (e.g., Run to Ride), the new workout was generated without checking that an older workout already existed on that date. Dual-sport days (AM/PM splits) still work correctly.

Sunday, April 5, 2026

  • Fixed training plan countdown resetting when re-opening the goal wizard. Previously, editing your goal settings would reset the start date to today, pushing the end date forward. The original start date is now preserved.
  • Fixed taper not reducing load enough when multiple A-races are close together. The taper now starts decaying relative to the first upcoming race instead of only the goal event, giving your Form proper time to recover before race day.
  • You can now ask Coach+ to rebuild your weekly plan. No more navigating to the Training Plan page. Just say "rebuild my plan" in chat.
  • Coach+ conversation starters are now context-aware. Instead of random suggestions, you'll see prompts based on what's happening right now: your latest workout, upcoming race, fatigue level, or rest day.
  • Coach+ now supports multiple conversations. Start a new conversation with the + button, switch between them with the list button, and each conversation gets an AI-generated title. Up to 30 conversations are kept.

Saturday, April 4, 2026

  • Improved workout scoring. Scores no longer cluster around 7 — the system now understands what intensity is appropriate for each workout type. Unscheduled workouts (group rides, spontaneous sessions) now also get a score based on training value: duration, intensity, and structure.

Friday, April 3, 2026

  • FTP Improvement goals now let you set a target FTP. Previously the goal had no way to set a specific watt target, falling back to your manual FTP which was often already exceeded. You now get the same FTP slider and AI-suggested targets as race goals.
  • Fixed sport selection during onboarding not being saved. Selecting cycling-only during setup had no effect, causing running workouts to still be generated. Sport preferences now correctly persist to your training schedule.
  • Fixed Coach+ chat sometimes getting confused about which day of the week maps to which date. The AI now receives a pre-computed day reference table instead of trying to calculate dates itself.
  • Workout names are now generated in your language. Previously, AI-generated workout names were always in English even when your app language was set to Spanish, Dutch, etc.
  • Fixed swim pull sets having only 30 seconds rest between 400m+ hard efforts. Rest is now 1.5 minutes, giving proper recovery between sustained threshold-pace pulls.
  • Consolidated Recovery Analysis and Insights sections on the Analytics page into one unified section. Recovery assessment, training gaps, and recommendations are now in a single card instead of two separate sections saying similar things.
  • Fixed training plan not updating after changing your training schedule. Previously, enabling/disabling days or changing workout durations in Settings required waiting for the weekly plan to regenerate on Sunday. Now the plan updates immediately when you change your schedule.
  • Fixed duplicate workouts appearing when a mountain bike ride, gravel ride, or virtual ride was already on the calendar. The system now correctly recognizes these as "Ride" variants and skips generating another ride on the same day.
  • Fixed daily workout and race-day emails failing for some athletes when the AI returned malformed JSON with missing colons. The system now automatically repairs this and retries.
  • Fixed running strides showing HR zone targets instead of pace. Heart rate can't respond fast enough for 20-second efforts, so strides and short bursts now always use pace targets even when HR mode is selected.
  • Fixed monthly progress email using technical terms "TSB" and "CTL" instead of the app labels "Form" and "Fitness". Also added guardrails against overstating fitness trends when the numbers don't support them.
  • Redesigned the readiness card with a unified layout. HRV, Sleep, and RHR now show for all athletes (not just Whoop users) when data is available from Intervals.icu. Metrics are organized in a cleaner grid with the ring showing Recovery or Form, and Fitness, Fatigue, RHR, and Ramp always visible below.
  • Fixed taper weeks sometimes showing higher TSS targets than peak weeks. The first taper week is now always capped at the peak level, ensuring a smooth load reduction into race week.
  • Fixed future week TSS targets sometimes showing stale values from a previous plan generation. Weeks beyond the next 7 days now reflect your latest fitness and periodization, while the current and next week keep their targets since workouts have already been generated for them.
  • Fixed double workouts appearing on the calendar after a weekly plan regeneration. When the plan changes, stale workouts from the previous plan are now automatically cleaned up.
  • Fixed running workouts being generated for cycling-only athletes who hadn't explicitly set their sport preferences. The system now defaults to cycling only when no sports are configured.
  • Fixed projected CTL showing different values on the Dashboard vs Training Plan page. Both pages now always show the same projection.

Thursday, April 2, 2026

  • Running workouts now support power-based targets. If you train with a running power meter (Stryd, Garmin, etc.), go to Settings > Training and select "Power-based" to get workout targets as % of your running FTP instead of pace. Great for hilly or windy routes where pace is unreliable.
  • Fixed post-workout analysis hallucinating "structured intervals" and "high-power sprints" on casual group rides. The AI now only describes interval structure when actual interval data supports it. Short Z6/Z7 spikes on group rides are correctly described as brief surges, not fabricated training sets.
  • Refined effectiveness scoring for unstructured rides. Long endurance rides and hard group rides still score well (7-8) based on real training value, but the score description will be honest about what happened instead of fabricating structured training.

Wednesday, April 1, 2026

  • Fixed weekly plan overwriting workouts that were already generated and uploaded to your calendar. When the plan refreshed on Sunday, it could create conflicting duration targets for workouts already on your schedule, causing mismatches between the dashboard and daily email.
  • Fixed removing a sport (e.g. unchecking Running) in Edit Schedule not persisting. The setting would appear saved but revert after the next plan generation.
  • Fixed fitness trend chart showing inflated CTL/ATL for users in eastern timezones (UTC+8 and beyond). The chart was using projected values that included planned workout TSS instead of your actual current fitness, causing a mismatch with the Training Overview card.
  • Daily adaptation now triggers earlier when your fatigue builds up. Previously it required a large fitness drop to replace a scheduled workout. Now it also catches cases where your Form is deeply negative, swapping high-intensity sessions for lower-intensity alternatives instead of defaulting to recovery.
  • Fixed post-workout analysis giving inflated scores (9/10) when you skip the planned workout and just ride. The system now detects when your actual zone distribution doesn't match the planned workout type and scores based on what you actually did.
  • Fixed post-workout analysis commenting on "hilly terrain" and power variability for indoor/ERG-controlled rides. Indoor rides now suppress terrain commentary since it's controlled by the trainer.
  • Post-workout analysis now uses "Form" instead of "TSB" to match the app terminology, and rounds CTL values consistently with the dashboard.

Monday, March 30, 2026

  • New Max feature: Performance Benchmarks! See how your fitness compares to peers on the Analytics page. Toggle benchmarks on to see P50 reference lines on your CTL, eFTP, power curve, weekly TSS, and running pace charts. Filter by age group and sex to compare against a relevant peer group. Available for Max subscribers.
  • The power profile radar and peak powers table now show peer P50 values so you can see where you stand at each power duration (5s sprint through 60min endurance).
  • Your age group and sex are now shown in Settings under your profile, sourced from Intervals.icu.
  • Fixed weekly plan ignoring LIMITED availability on holiday events. If you mark a holiday as "Limited" in Intervals.icu with specific sports allowed (e.g. Run only), IntervalCoach now schedules workouts in those sports instead of skipping the day entirely. Max training time is also respected.

Sunday, March 29, 2026

  • Public athlete profiles are here! Share your training milestones with a public profile page. Go to Settings > Account > Public Profile to enable yours, customize your handle, and share the link. Your profile shows earned badges, peak fitness, and training stats.
  • The Coach+ chat counter now shows when your monthly credits reset (e.g. "14/20 · Resets Apr 1") so you can pace your usage.
  • Fixed race pace plans giving cycling warmup instructions (spinning, power targets) for running and trail run events. Warmup guidance is now sport-appropriate.
  • Added training milestone badges! Earn badges for volume (Century Day, Big Week, Monster Week), consistency (7-day and 30-day streaks, Plan Follower), fitness gains (FTP Bump, New Peak CTL, Power Surge), recovery (Rest Day Respect), and multi-sport training. Badges appear on your dashboard and you get an email notification when you unlock a new one. Toggle badge emails in Settings > Notifications.
  • Badges now include repeatable challenges: Monthly Century (100+ TSS day each month), Perfect Month (4 weeks of 90%+ adherence), and Annual Warrior (200 training days per year). Plus tenure milestones at 3 months, 6 months, 1 year, and 2 years.
  • Unearned badges show progress bars so you can see how close you are (e.g. "4/7 days" toward a streak). Earned badges show what percentage of athletes have unlocked them.

Saturday, March 28, 2026

  • Added body weight trend chart to the Analytics page under Wellness & Recovery. If you log weight in Intervals.icu, you can now see your weekly average weight over time.
  • Coach+ can now access your weight history. Ask about your weight trend, body composition, or W/kg changes and the coach will pull your data from Intervals.icu.
  • Fixed Threshold Surges workouts generating an excessive number of intervals for long rides. A 3h50m ride would previously fill the entire session with 19 threshold blocks instead of capping at a reasonable number and padding with endurance.
  • Fixed readiness score display for Polar users. Polar reports readiness on a 1-6 scale which was being misinterpreted, causing squashed graphs. Now correctly maps Polar values to percentages (e.g. 5 "Good" → 75%).
  • Reduced reconnect email spam for users who decline write permissions. If you use IntervalCoach in read-only mode (dashboard and analytics only), you will no longer receive daily reconnect emails.
  • Fixed Notes in Intervals.icu blocking the unavailability toggle in the training plan view. Notes no longer appear as 0min/0TSS entries in the day plan grid.

Friday, March 27, 2026

  • You can now schedule TrainNow workouts for a future date. Pick any upcoming day from the calendar and the workout will be uploaded to that date instead of today.
  • Updated privacy policy with detailed AI data sharing disclosure: what training data is sent, which providers process it, and how your privacy is protected.

Thursday, March 26, 2026

  • Fixed training plan TSS targets not accounting for periodization overhead. Peak, taper, and recovery weeks reduce effective TSS below the base target, making CTL goals mathematically unreachable even with perfect adherence. Build weeks are now inflated to compensate, respecting your periodization settings and availability.
  • Fixed changing the sport on a planned workout in the training plan view. Previously, switching a planned Ride to a Run (or vice versa) would fail with "Entry not found" because the lookup used the new sport instead of the original.
  • Fixed weekly plans generating fewer sessions than requested for athletes with 5-6 desired sessions per week. The rest-day spacing rule now scales with the number of requested sessions instead of enforcing a fixed maximum of 3 consecutive training days.

Wednesday, March 25, 2026

  • Fixed training recommendations being too conservative for athletes without a readiness score (e.g. Garmin users). Previously, a normal day-to-day HRV dip of -14% could trigger a recovery-only workout recommendation even when all other signals were green. Recovery assessment is now based on the full signals system (HRV, sleep, training load, fatigue, biometrics) instead of HRV alone.
  • Fixed weekly plans dropping Saturday workouts for high-volume athletes with multi-session days. Athletes with more desired sessions than training days (e.g. 14 sessions across 7 days) now keep all their configured days instead of having sessions removed by the rest-spacing rule.
  • Fixed long endurance rides with brief sprints being misclassified as "anaerobic" stimulus. A 5h Z2 ride with 2 minutes of Z6/Z7 is now correctly classified as "endurance" instead of "anaerobic".
  • Weekly summary emails now reference your actual planned workouts for next week instead of generic AI advice that could contradict the plan.
  • Improved workout variety: the recency penalty now lasts 3 weeks instead of 2, so the same workout is less likely to repeat week after week. Especially noticeable in Base phase endurance days.
  • Daily workouts now incorporate your coaching memories (learned from past conversations) into workout type selection, not just custom instructions. If you told Coach+ you prefer short VO2max intervals or want to avoid long threshold blocks, that now influences which workout gets picked for your daily plan.

Tuesday, March 24, 2026

  • Fixed completed activities not appearing on the calendar after syncing from Strava. The activity cache was not being refreshed when new activities arrived, so the calendar could show stale data for up to 4 hours even after clicking refresh.

Monday, March 23, 2026

  • Fixed Progressive Load and Zone 2 Quality charts not showing data for gravel rides, mountain bike rides, and e-bike rides. These activity types were accidentally excluded from the analytics calculations.
  • Fixed past weeks' TSS targets being recalculated when changing training settings. Past weeks now always keep their original targets, so your historical progress tracking stays accurate.

Saturday, March 21, 2026

  • Redesigned the calendar page with richer workout cards showing name, duration, and TSS at a glance. Completed activities have green borders, planned workouts show their event color, and upcoming plan placeholders appear with dashed borders so you can see what's coming before the workout is generated.
  • Added drag-and-drop to the calendar. Drag planned workouts or placeholders to a different day to reschedule them. Works for both Intervals.icu events and weekly plan entries.
  • The calendar now shows weekly summary data: total time, sport breakdown, and TSS progress alongside the week type badge.
  • Mobile calendar switched from a cramped 7-column grid to a vertical list view. Only days with workouts are shown, with larger touch targets and better readability.
  • Fixed swim workouts being much shorter than requested. Intensity swim sessions (VO2max, sprints, etc.) now fill remaining time with endurance swimming after the main set, matching how real swim coaches structure sessions.
  • Fixed weekly plan skipping days that only have strength training on the calendar. You can now get endurance workouts on days you also do weights.

Friday, March 20, 2026

  • Added power profile radar chart and power-duration curve to Analytics. The radar shows your strengths across 8 durations (5s to 20min) with each axis scaled to your peak, so you can instantly see your sprinter vs TT profile shape. The curve chart shows your full power-duration relationship with current vs all-time overlay.
  • Fixed the "Required hours" display escalating each time you increased your training schedule. The required hours now stay stable based on your CTL target, giving you a fixed goal to work toward.
  • Fixed deleted race events in Intervals.icu still showing peak/taper phases on the training plan calendar. The cache now refreshes automatically when events are added or removed.
  • Fixed workout generation silently failing on iOS PWA. You now get a clear timeout message instead of a blank error, and the server has more time to complete generation.
  • Fixed dashboard showing "Planned Rest Day" on days that have a workout in the weekly plan but the calendar event hasn't been generated yet.

Thursday, March 19, 2026

  • Added Alipay as a payment option at checkout, making it easier for users in China to subscribe.
  • Post-workout email now shows your CTL and TSB before and after the workout, so you can see exactly how each session contributes to your fitness.
  • Fixed training plan completion percentage showing incorrect values when manually added workouts push the week's total TSS above the original target. The percentage now correctly reflects the raised target.

Wednesday, March 18, 2026

  • Fixed weekly plan overloading remaining workout days when you have manually planned workouts on your Intervals.icu calendar. The plan now deducts the TSS from your manual workouts before distributing load across the days it generates.
  • Swimming workouts now use distance-based intervals (e.g., 100mtr, 200mtr) instead of time-based, so they display correctly in Intervals.icu with proper Pace/100m targets based on your CSS.

Tuesday, March 17, 2026

  • Workout ramp segments with trivial power ranges (3% or less) are now output as steady-state instead of meaningless ramps. A "75-76% ramp" in ERG mode was indistinguishable from flat power.
  • Fixed weekly TSS targets not updating when you change your periodization week-in-cycle. Previously, changing a Build week to Recovery in settings would show the Recovery label but keep the old Build-level TSS target and generate full-volume workouts.

Monday, March 16, 2026

  • Fixed Peak phase only assigning Sweet Spot and Endurance workouts instead of VO2max and Anaerobic. Athletes approaching their goal event now get race-specific intensity as intended.
  • Training plan now shows both planned placeholders and real workouts from your calendar side by side, so you can see exactly what has been generated and what is still upcoming.
  • Training plan: placeholder workouts now show a dashed border and tooltip to distinguish them from generated workouts on your calendar.
  • Training plan: you can now edit the workout category (Recovery, Endurance, Tempo, Sweet Spot, Threshold, VO2max, Anaerobic) on placeholder workouts. The intensity flag is automatically derived from the category.
  • Training plan: manually added, edited, or moved placeholders now survive weekly plan regeneration instead of being overwritten every Sunday.
  • Training plan: manually deleted placeholders are no longer re-added when the plan regenerates.
  • Fixed Coach+ chat not being scrollable on iPhone. Auto-scroll now pauses when you scroll up to read earlier messages, and pull-to-refresh no longer hijacks scroll gestures in Safari and Arc.
  • Fixed individual workout TSS targets sometimes exceeding physiological limits when your training history showed unusually high intensity rates.

Sunday, March 15, 2026

  • Fixed running workouts ignoring the Heart Rate-based target setting. Workouts now use HR zone format (Z1-Z5 HR) when you select Heart Rate-based in settings, which Intervals.icu and Garmin recognize as structured targets with actual HR guidance on your watch.
  • Fixed the Running Pace Preference setting (Critical Speed vs Manual Threshold) being ignored. Running zones and workout paces now correctly use your chosen pace source instead of always defaulting to Critical Speed.
  • Your coaching instructions and coach memories now influence workout selection. Instructions like "focus on threshold" or "avoid VO2max" will nudge both TrainNow recommendations and daily workouts toward your preferences.
  • Fixed swim workout TSS running 50%+ higher than planned. Endurance swims now produce ~45 TSS/hr instead of ~75, matching the intended training load.
  • Cadence pyramid workouts now ramp intensity alongside cadence (tempo at 70rpm → threshold at 110rpm) instead of holding flat power across all cadence steps.
  • Sweet spot dense workouts now fit within the requested duration instead of sometimes running 7 minutes over.
  • Swim pacing workouts now use progressive 92-100% CSS pace with adequate recovery, instead of fixed threshold intervals at 100% CSS.
  • Longer swim sessions (60min+) now get proportionally longer warmups and cooldowns.
  • Recovery rides no longer get inflated TSS targets from weekly plan surplus distribution.
  • Fixed false "volume jump" warnings in TrainNow that could force unnecessary recovery workouts. The previous week's training load was being calculated from only 1-2 days of data instead of the full 7 days.
  • New Pyramidal periodization model: 75% easy, 15% moderate (tempo/sweet spot), 10% hard. A research-backed alternative to Polarized training for athletes who respond well to sustained tempo and sweet spot work.
  • Analytics now shows your actual training pattern (Base, Polarized, Pyramidal, Threshold, or High Intensity) alongside the polarization index, so you can see if your real distribution matches your intended model.
  • Distribution drift detection: analytics flags when your recent training pattern has shifted from your longer-term trend (e.g. "Shifted from Polarized to Threshold").
  • New training monotony detection: the system now tracks daily training load variation and warns when monotony is too high (Foster 1998), reducing overuse injury risk.
  • New load-recovery ratio: compares your weekly training load against your recovery score to detect when load outpaces recovery capacity.
  • Phase-aware signal thresholds: during Build phases, more warning signals are needed before training is modified (3 vs 1 during Taper), so expected fatigue accumulation does not trigger unnecessary reductions.
  • New ACWR (Acute:Chronic Workload Ratio) tracking: detects training load spikes by comparing your recent 7-day load against your 28-day average. Ratios above 1.5 trigger automatic load reduction to lower injury risk (Gabbett 2016).
  • New aggregate durability tracking: monitors your Efficiency Factor (EF) trends across qualifying endurance sessions (90+ min, endurance pace), comparing 7-day vs 28-day averages to detect improving, stable, or declining aerobic fitness.
  • New training consistency index: tracks how well you follow your planned weekly TSS targets. Shows compliance status (on track, partial, below target) and per-week breakdown to help identify schedule adherence patterns.

Saturday, March 14, 2026

  • New training goal templates: you can now set a training goal without having a race. Choose from General Fitness, Return to Sport, Off-Season Base, Weight Management, Speed/Power Block, or Maintenance — each with its own phase model and duration. Available in onboarding and settings.
  • Fixed training plan projection charts (CTL, Form, Ramp Rate) curving backward instead of moving forward in time.
  • Fixed goal events more than 1 year away (e.g. Ironman France 2027) not appearing in training plan setup. The lookup window now extends to 2 years.
  • Fixed swim workout TSS calculation producing wildly inflated values (e.g. 3046 instead of ~60) by correctly mapping swim pace percentages to intensity factors.
  • Tempo workouts now target mid-zone intensity (~82% FTP) instead of the zone ceiling (87%), making sustained tempo efforts more realistic and sustainable.
  • Fixed workout duration overruns for openers, sweet spot, and swim VO2max workouts where generated segments exceeded the requested duration.
  • Fixed workouts being significantly shorter than your configured availability. Athletes with high training hours but lower CTL were getting 60-70 minute rides on 2-hour slots because the weekly TSS budget was too low to fill the available time at endurance intensity. The plan now ensures weekly TSS targets respect your scheduled training hours.
  • Fixed a bug where upgrading your subscription (e.g. Pro to Max) could leave the old subscription active, causing duplicate billing. Old subscriptions are now automatically cancelled on upgrade, and renewal events from stale subscriptions no longer overwrite your current plan.
  • Fixed the Contact button doing nothing on mobile. It now opens your email app instead.
  • Improved swim workout quality: sprint, anaerobic, recovery, threshold, and endurance workouts now have distinct structures with intensity progression, proper rep caps, and duration scaling. Sprint workouts split into 3 types (short sprints, anaerobic repeats, sprint ladder) instead of all using the same pattern.
  • Fixed swim workout TSS estimation ignoring long endurance steps (25+ minutes), which caused TSS accuracy checks to fail on endurance and steady-state swim workouts.
  • New swimmer-specific strength workout with shoulder stability, rotator cuff, and pull exercises. Strength workouts now better match your primary sport instead of defaulting to generic templates.
  • New Mobility & Recovery strength session with stretching, foam rolling, and flexibility work for recovery and transition weeks.
  • Improved strength workout variety: less repetition across sessions (different core exercises per template), phase-aware volume guidance (lighter/higher reps in Base, heavier/lower reps in Build), and the quick core routine is now available for all sports.

Friday, March 13, 2026

  • Smarter daily TSS distribution: your training plan now allocates TSS based on the specific workout category (VO2max, threshold, endurance, etc.) instead of a simple intensity/endurance split. This means your VO2max days get a realistic TSS budget and endurance days aren't shortchanged, leading to better workout selection and less type-shifting.

Thursday, March 12, 2026

  • Fixed B-race goals being misidentified as A-races in the coaching pipeline. The coach now correctly recognises your race priority (A/B/C) when generating workout advice, taper recommendations, and chat responses.
  • Fixed AI Coach note incorrectly identifying mid-week Build phases as a "deload pattern." The coach now compares the same days of the week (e.g. Mon–Thu this week vs Mon–Thu last week) rather than a partial week against a full previous week, eliminating false TSS drop signals.
  • Fixed SS Intervals workout generating only 3 large blocks instead of the expected 6×5-minute structure. SS Intervals now use a dedicated generator producing short 5-minute efforts with 2-minute recoveries, correctly scaling to 6+ intervals for a 60-minute session.
  • Fixed 4 workout types sharing the wrong generator and producing incorrect structures: Sweet Spot Cadence now alternates low/high cadence blocks; Tempo Blocks now uses 5-8 min efforts (not 8-12 min); Cruise Intervals now targets the correct SS/threshold zone intensity (not tempo zone); Anaerobic Capacity now uses 60-second efforts with 4-minute recovery (not 20-second sprints).
  • Fixed pre-race day workouts (openers) being assigned too much TSS, causing the generator to push intensity beyond what the workout type can produce. Pre-event days now get a realistic TSS budget and freed TSS is redistributed to other training days.
  • Added example prompts and guidance for custom coaching instructions to help you get the most out of the feature.
  • Coach+ can now update and delete your race events (A/B/C) directly in chat.
  • Changing your CTL target now instantly updates your weekly TSS targets without rebuilding the entire training plan.
  • Improved workout variety: you'll now see a much wider range of workout types instead of the same 3-5 repeating. Category-level recency tracking ensures you don't get similar workouts back-to-back, and all 100+ catalog workouts are now reachable across training phases.
  • New workout types: force intervals, sprint pyramids, Rønnestad 30/15s, contrast intervals, cadence pyramids, and more micro-interval variations for both cycling and running.
  • Fixed race simulation workouts using tempo zones (76-87% FTP) instead of threshold zones (85-105% FTP) for the main blocks.
  • Fixed TrainNow allowing swim-only workout types to be selected for cycling or running sessions.
  • Coach+ can now build fully custom workouts from scratch. Describe any workout structure in natural language (e.g. "5x5min at 105% with 2min rest" or "a pyramid of 1-2-3-4-3-2-1 minutes") and preview it before adding to your calendar.
  • Fixed swim workouts showing "(0w)" and an empty power chart in Intervals.icu. Steps are now formatted as percentage of CSS (Critical Swim Speed) pace instead of FTP power, so the swim chart renders correctly.
  • Fixed Coach+ custom swim workouts occasionally generating absurd durations (e.g. 3h50m) when the AI confused meters with minutes. Workouts are now validated and capped at a sensible maximum duration, and the schema guidance now explicitly clarifies that times are in minutes.
  • Fixed Coach+ scheduling workouts on a future planned swim/ride/run day instead of today when you ask for a workout without specifying a date.

Wednesday, March 11, 2026

  • Fixed daily email showing "Scheduled" for rest days during recovery weeks. When fewer workouts are planned (e.g., 4 instead of 6), the remaining days now correctly show as rest.
  • Fixed ultra-distance cycling events being misclassified as running goals, which caused too many running sessions in the weekly plan.
  • Weekly plans now prioritize your goal sport when distributing sessions. If your goal is a cycling event, you'll get more cycling sessions and fewer runs (and vice versa).
  • Fixed Sweet Spot workouts prescribing VO2max-level intensities (101-108% FTP instead of 88-94%). Zone calibration was shifting zone boundaries upward, producing dangerous intensity targets.

Tuesday, March 10, 2026

  • New Training Demand control on the Training Plan page — quickly adjust your training intensity with Easy (-25%), Moderate, Demanding (+15%), or Aggressive (+30%) settings. Your weekly TSS targets update instantly across the entire plan.
  • Fixed training plan showing impossibly low TSS targets (e.g., 9 TSS for a 2-hour ride) when CTL is low but training volume is high. Weekly TSS now respects a minimum floor based on your scheduled training hours.
  • Improved CTL target wizard accuracy for athletes who recently started training or ramped up significantly. The wizard now accounts for recent training load (ATL) when it significantly exceeds long-term fitness (CTL).
  • Generated workouts are now more reliable and consistent. Duration, structure, and intensity are always accurate, with personalized warmup and cooldown messages tailored to you.
  • Improved workout variety with new cycling, running, and swimming workout types including descending VO2max, progressive threshold, race simulations, and more.
  • Fixed workout duration calculator not counting seconds-only intervals (e.g., 30s sprints, 45s surges), which caused workouts with short intervals to appear much shorter than they actually are.
  • Fixed fallback workout templates (2x20 FTP, Progressive Sweet Spot, FTP Test, Openers, VO2max Pyramid) always producing the same duration regardless of the requested time. A 150-minute 2x20 FTP request now correctly produces a 150-minute workout with Z2 endurance around the core intervals, instead of always outputting 70 minutes.
  • Fixed Training Intensity Distribution chart tooltip showing incorrect percentages (e.g., 6000% instead of 60%).

Monday, March 9, 2026

  • New Training Science section on the Analytics page with three metrics: Training Intensity Distribution (time-based easy/moderate/hard split with polarization index), Zone 2 Quality (scores your endurance rides for gray zone drift), and Efficiency Factor trending (tracks aerobic fitness via NP/HR over time).
  • The Training Stimulus card on the dashboard now shows a 3-color intensity distribution bar (easy/moderate/hard) based on actual time in zones, replacing the previous 2-color session count bar. Includes your periodization model target for comparison.
  • Post-workout AI analysis now flags gray zone issues on endurance rides and compares your Efficiency Factor to your recent average.
  • Fixed multi-sport athletes (triathletes) getting only easy/recovery workouts for some sports. Intensity sessions are now distributed across all endurance sports instead of concentrating in one or two.
  • Coach+ chat now automatically recovers from corrupted conversation errors instead of showing an unrecoverable Retry button. If the error occurs, the conversation resets and the next message works normally.

Sunday, March 8, 2026

  • Improved Zone Development scoring: zones are now scored by comparing your current power curve against your all-time best at each energy system duration (30s for anaerobic, 5min for VO2max, 8min for threshold, 20min for tempo, 60min for endurance), giving a meaningful 0-10 score instead of always maxing out.
  • Redesigned the Zone Development card to show percentage of peak (e.g., "80% of peak"), trend indicators (improving/stable/declining), and reference durations. Tap a zone to see your current watts vs all-time best.
  • Added Form (%) and Ramp Rate projection charts to the Training Plan page, showing how your freshness and training load rate of change are expected to evolve alongside your CTL trajectory
  • Fixed activity detail dialog crashing when opening activities synced from Strava or other sources that do not include an activity type (e.g. on the calendar page on Android).
  • Unified workout detail dialog — clicking any workout or activity opens an intelligent dialog that shows structure and nutrition for planned workouts, and performance data with AI analysis for completed activities
  • Clicking a completed workout on the dashboard now opens your actual results (power, zones, AI analysis) instead of the planned workout structure
  • Added energy tracking to workout details — see calories burned (kcal/kJ) from your device data, or smart estimates when device data is missing
  • Added post-workout nutrition advice for today's completed activities with recovery-focused recommendations

Saturday, March 7, 2026

  • Fixed C events (group rides, fondos, etc.) not showing as completed on the dashboard after finishing the ride. The event card now correctly shows the "Completed" badge instead of still displaying the upcoming event.
  • Fixed Coach+ chat occasionally failing with "Something went wrong" when empty messages were sent to the AI. The chat now validates message content before processing.
  • FTP tests are now automatically scheduled into your weekly plan based on your frequency setting (every 4, 6, 8, or 12 weeks). Previously the setting existed but had no effect — you had to manually ask Coach+ to create a test.
  • Fixed Training Stimulus card incorrectly counting weight training sessions as high-intensity workouts. HR spikes during lifting (e.g., heavy squats) were being classified as threshold or VO2max sessions, skewing the intensity distribution and showing "Not Polarized" warnings for well-structured training.
  • Fixed AI coaching note showing wildly inflated week-over-week TSS percentages (e.g., "3231% increase") for athletes training multiple sessions per day. The system was limiting to 14 activities by count instead of by time window, cutting off previous week data.
  • Fixed Zone Progression and Focus Areas showing 0.0 for all zones. Some Intervals.icu accounts return zone time data in a numeric array format that was not being handled correctly.
  • Fixed workouts being named "VO2max" when the actual content was Z2 endurance. The workout name now reflects the actual generated content instead of always using the planned type.
  • Fixed AI weekly coaching notes complaining about training load even when you hit your weekly TSS target. The AI now sees your actual progress vs target so it can accurately assess whether you are on track.
  • Fixed dashboard showing "Ready to Train" with green signals after training on a scheduled rest day. The readiness widget now respects the rest day violation and recommends rest.
  • Fixed dashboard still showing "ready to tackle today's session" after completing a workout. The workout card now reliably shows a "Completed" badge instead.
  • Fixed "Days consec" counter always showing 0 on the dashboard. The consecutive training days calculation was using the server's UTC date instead of your local timezone, causing it to miss matching activity dates.

Wednesday, March 4, 2026

  • Post-workout effectiveness score is now based on Intervals.icu compliance % instead of AI judgment. A workout where you only completed 30% of the plan now correctly scores 3/10 instead of the AI giving 8/10.
  • Fixed Coach+ chat crashing with "Something went wrong" when viewing running performance profiles. The performance profile card now handles missing or incomplete running data gracefully instead of crashing.
  • Fixed Coach+ failing to replace or delete workouts when the AI used placeholder names instead of real event IDs. The chat now validates event IDs before making calendar changes.
  • Fixed workouts being scheduled on days that already have a race or event (A/B/C events). The system now detects race events on the calendar and skips those days.
  • Fixed deleted workouts (rest days) being automatically refilled the next day. The system now remembers which workouts it already generated, so removing a workout to take a rest day is respected.
  • Fixed changing a run to a bike workout causing the system to reschedule a new run. User modifications to workout sport are now preserved.
  • Fixed post-workout analysis showing "Workout compliance N/A" for unscheduled activities. Compliance is now only shown when a planned workout exists, and the effectiveness reason text is consistent with the score.

Tuesday, March 3, 2026

  • Fixed Coach+ silently deleting existing workouts when generating a new one on the same day. The AI now explicitly identifies which workout to replace instead of automatically removing all IntervalCoach workouts on that date.
  • Fixed weekly workouts not appearing on the calendar after the Sunday plan generation. The system was only filling one missing day per daily run, so it could take nearly a week to populate your full schedule. Now all missing workouts are created at once.

Monday, March 2, 2026

  • Coach+ chat now shows rich visual cards for tool results instead of plain text — workouts display with a zone-colored chart, training status shows a metric grid, nutrition advice renders as an expandable card, and more. Applies to 9 tools including activity details, performance profile, wellness, warnings, and activity search.
  • Fixed Coach+ describing workout actions in prose without actually calling the tools. The AI now always previews the action and calls the tool in the same response, so you see the Approve/Cancel prompt immediately.
  • Fixed Coach+ ignoring specific workout instructions like "15 hill repeats" or "focus on cadence drills". Your exact request is now passed through to the workout generator.
  • Fixed Coach+ creating duplicate workouts when asked to replace an existing workout. The AI now correctly replaces the targeted workout instead of creating a second one.
  • Fixed workouts being generated on disabled training days after changing your schedule. The system now checks the live training schedule before creating workouts, even if the plan hasn't regenerated yet.
  • Fixed Calendar and Training Plan pages showing different training phases for the current week. The Calendar now uses the same phase source as the Training Plan when the plan projection isn't available.
  • Fixed dashboard fitness metrics (CTL/ATL/TSB) now including today's completed workouts — previously only yesterday's values were shown, so a morning ride wouldn't be reflected until the next day

Sunday, March 1, 2026

  • Fixed endurance workouts sometimes generating a single 45-minute continuous ramp instead of steady-state blocks. Progressive workouts now use stepped power blocks, and any AI-generated ramp in the main set is automatically caught and replaced with a proper workout structure.
  • You can now move and delete generated workouts in the upcoming week on the Training Plan page. Previously the action menu was missing for these workouts.
  • The Training Stimulus card no longer flags "too much high intensity" when you're following the AI-generated plan. It now checks your actual hard sessions against what was prescribed, and only warns if you exceed the plan.
  • The Weekly TSS chart in Training Analysis now responds to the timeframe selector, matching the behavior of the Fitness Trend and Zone Progression charts.
  • Fixed a dashboard crash that could occur when readiness data was still loading.
  • Fixed bottom navigation tabs (Coach+ and More) being cut off on iPhones in portrait mode.
  • Fixed Coach+ creating duplicate workouts when regenerating or replacing workouts on the same day. The AI now explicitly targets which workout to replace, preventing accidental duplicates.
  • Fixed daily workouts generating at roughly half the planned TSS target — the AI was not receiving the session-level TSS target from your training plan, resulting in consistently under-prescribed workouts.
  • Fixed wellness data (resting HR, sleep, recovery) surfacing stale values from days or weeks ago as if they were current. The system now only reports today's wellness data — if no data is available today, it shows "Unknown" instead of misleading old values.
  • Fixed Coach+ sometimes showing raw tool output (JSON data) in chat responses. Chat now uses the AI SDK's native message persistence, preserving full conversation context including tool metadata. This eliminates the workaround that was causing tool output leaks and improves chat reliability.

Saturday, February 28, 2026

  • Fixed sick/injured status persisting one day too long — if you marked a single day as sick on Intervals.icu, IntervalCoach would still show you as sick the next day. Now correctly clears when the sick day is over.
  • Fixed strength workouts being duplicated on the calendar — each cron run added another copy because the idempotency check didn't recognize existing strength workouts. Now correctly detects them and skips re-generation.
  • Fixed post-workout analysis email saying "no power data" for rides that had power in their intervals but a missing activity-level average. Power is now detected from interval data as a fallback.
  • Fixed generated workouts ignoring your RPM preferences (e.g., "never above 85rpm") when adding cadence variety. Your cadence preferences now take priority over default variety targets.
  • Fixed dashboard showing redundant alternative advice (e.g., "stay in Z2") when the scheduled workout is already a Z2 endurance ride.
  • Fixed tempo workouts being mislabeled as "Threshold" in post-workout analysis when their intensity factor was near the threshold range.
  • Fixed Coach+ chat sometimes fabricating which activity produced a peak power value. The AI now correctly explains that peak powers are aggregate all-time bests without activity attribution.
  • Fixed Coach+ directing users to the wrong page for training availability settings. It now correctly points to the Training Plan page (Training Volume section).
  • Fixed daily email coaching note sometimes referencing a planned workout that was deleted or skipped. The AI now only references actually completed activities.
  • Fixed Race Simulation workouts being generated at endurance intensity (~65% FTP) during taper/deload phases. High-intensity workout types now maintain their prescribed power targets, with the intensity modifier reducing volume (fewer reps) instead of dropping power below race pace.
  • Dashboard no longer shows "Today: Rest Day" recommendation after you've completed a workout. The training recommendation and alternative advice are hidden once you're done training for the day.
  • Form metric now shows raw TSB value (e.g., "-30 TSB") matching Intervals.icu, instead of the percentage that was confusing users.
  • Improved workout variety — workouts you've done recently are now deprioritized with a time-decay penalty, so you cycle through more of the 30+ workout types instead of getting the same one back-to-back.

Friday, February 27, 2026

  • Dashboard now automatically refreshes when you return to it after 5+ minutes — newly synced activities and updated fitness data appear without needing to manually hit the refresh button
  • Coach+ can now mark dates as unavailable directly from chat — tell it "I'm away March 5–7" and it will update your training plan schedule and ask if you want to remove any existing workouts on those days
  • All emails now include an Unsubscribe link in the footer that takes you directly to your notification settings, as well as a physical mailing address for compliance.
  • Fixed workouts occasionally exceeding your configured availability (e.g. 2h38m for a 2h window) — the AI now strictly requires a duration on every workout step, and workouts with missing durations are caught and regenerated
  • Fixed: Coach+ chat occasionally failed with an internal error mid-conversation when using tools (e.g., generating or moving workouts). Conversations should now stay stable regardless of how many tool calls occur.
  • Fixed: holiday and vacation events on Intervals.icu now block workout scheduling on those specific days — previously the weekly load was reduced but workouts were still placed during your vacation. Holiday days also appear as unavailable in the training plan week view.

Thursday, February 26, 2026

  • Training plan timeline now shows target and actual load in one chart — see at a glance how your training tracked against the plan across the whole season.
  • The training plan now shows last week's completed workouts and this week's planned workouts — both expand automatically so you can see the full picture alongside upcoming weeks.
  • IC-generated workouts in the current week now have move and delete actions — use the ⋮ menu on any planned workout to reschedule it to another day or remove it entirely.
  • Fixed: dashboard Load and Form signals were inflated by planned (not yet completed) workouts, causing false rest-day recommendations and unnecessary recovery-ride swaps. Values now reflect only what you've actually done.

Wednesday, February 25, 2026

  • Added training signal health panel to the dashboard — shows Recovery, Sleep, HRV, Load, and Biometrics status at a glance. Expands automatically when signals are active, collapses to a minimal summary when everything looks good.
  • Training signals now fully wired: fatigue indicators (HRV trend, RHR trend, overreaching risk) are computed and fed into adaptation signals across the dashboard, TrainNow, and Coach+ chat — so workout recommendations reflect your true recovery state rather than surface wellness alone.
  • Added HRV Stability (CV) to the analytics page — a new chart shows your week-to-week HRV consistency based on the coefficient of variation, with green/amber/red bands so you can see at a glance whether your autonomic nervous system is stable or volatile
  • HRV-CV now appears in the HRV summary card on the analytics page, giving you a quick stability reading alongside your average HRV
  • The AI coach now considers your HRV stability when generating workouts — if your week has been physiologically volatile (CV > 25%), it favors moderate intensity even when your daily HRV looks normal

Tuesday, February 24, 2026

  • You can now override the weekly TSS target for any upcoming week in your training plan — click the TSS number on a future week to set a custom target, and the CTL projection updates instantly to reflect your adjusted plan
  • Mark dates as unavailable with the new blackout days feature — tap any future day in the week table to block it off, and the planner will redistribute your training around your time off
  • Added an "Add workout" button to locked (current) weeks in the training plan — you can now fill gaps in your schedule even after the week has started
  • Fixed Target CTL fluctuating wildly week-to-week (e.g. 46 → 60 → 85 → 46) when no CTL target was set — the system was auto-generating a target from the projection which changed on every recalculation; the target now only shows when you've set one via the CTL wizard
  • Fixed free tier users not receiving rolling daily workouts — workout generation was gated behind a flag that only applied to paid users
  • Fixed mid-week plan regeneration leaving empty days when workouts were already generated for some days — gaps are now filled with placeholder workouts so every training day has a plan
  • Fixed Coach+ chat being unscrollable on iOS Safari — conversation history can now be scrolled with native momentum
  • Fixed single-day A races being incorrectly detected as 2-day events — Intervals.icu returns midnight of the next day as the end time for events with duration set, which was inflating taper and phase calculations
  • Fixed HRV and resting heart rate analysis giving confident recovery assessments with only a few days of data — the system now requires at least 14 days of baseline data before drawing conclusions from z-score deviations
  • Fixed transition steps being incorrectly placed inside repeat blocks — steps like "Transition to finish" were repeated with every interval instead of running once, inflating workout duration estimates

Monday, February 23, 2026

  • Workouts now appear on your calendar one day at a time instead of all at once on Sunday — each workout is generated 7 days ahead, so your calendar fills in gradually throughout the week
  • You can now edit upcoming planned workouts directly from the calendar — change the sport, duration, TSS target, intensity, move it to another day, or delete it entirely before the workout is generated
  • Improved workout variety — the AI now checks what you did the previous day and avoids scheduling the same workout type on consecutive days

Sunday, February 22, 2026

  • Activity detail now shows comprehensive interval data — work intervals are visually distinguished from rest, with expandable rows showing power (NP, W/kg, L/R balance, work kJ), running metrics (stride, GAP, max speed), plus TSS, decoupling, elevation, and temperature
  • Fixed race day email not being sent when a warmup workout was also scheduled on the same day — the system could pick up the workout first and never detect the A/B race event, resulting in a regular training email instead of race day guidance
  • Fixed daily adaptation replacing pre-race warmups, cooldowns, and FTP tests with endurance rides — these user-intentional workouts are now protected from automatic adaptation
  • Fixed Coach+ chat erroring on custom questions — improved error handling for tool calls so the AI recovers gracefully instead of showing "Something went wrong"
  • Fixed weekly plan sometimes generating workouts much longer than the available time slot — the AI occasionally produced descriptive step lines without duration markers, making the duration estimate unreliable; the system now detects this and falls back to a template workout that respects your schedule
  • Fixed interval/lap data not appearing in activity details despite the recent fix — the Intervals.icu API response format was parsed incorrectly, so interval power, HR, cadence, and pace data was silently dropped
  • Fixed training plan showing negative TSS and training hours for future weeks when your current fitness exceeds what the goal requires
  • Fixed dashboard occasionally crashing when AI generates JSON with trailing commas in goal analysis or readiness messages
  • Fixed activity detail page failing to load for Strava-sourced activities — the intervals endpoint returns an error for Strava activities due to API restrictions, which now gracefully falls back to showing the activity without interval data
  • Fixed post-workout analysis misclassifying sweet spot and threshold workouts as endurance — the AI now receives a metrics-based classification hint so workouts like TrainerRoad's "Rosa" (IF 0.87) are correctly identified as sweet spot
  • Fixed navigation tabs being invisible on tablet screens — inactive tabs blended into the header background, making it appear only the active page was selectable

Saturday, February 21, 2026

  • Fixed warmup ramps starting at 0-1W on smart trainers — recovery and endurance workouts now start at a rideable 40% FTP minimum instead of the scientifically-correct-but-impossible 0W floor
  • Fixed training plan showing wrong completion percentage for the current week — e.g. showing 110% when actual TSS was 461 of a 567 target (should be 81%)
  • Fixed AI coaching note week-over-week TSS comparison using rolling UTC windows instead of proper Monday-to-Sunday calendar weeks — this could show inaccurate training load changes, especially for athletes in timezones far from UTC
  • Fixed activity interval/lap data always showing as empty — the AI coach, post-workout analysis, and activity detail page now show per-interval power, HR, cadence, and lactate data from your completed workouts
  • Fixed calendar events marked "busy", "unavailable", or "off" not being detected as time off — the coach could schedule workouts on days you marked as unavailable

Friday, February 20, 2026

  • Introducing Coach+ — chat directly with your AI coach to ask training questions, review your readiness, look up past activities, adjust your weekly plan, get race strategy advice, and more. Available for Pro (20 messages/month) and Max (200 messages/month) subscribers.
  • New Max plan — everything in Pro plus 10x more Coach+ messages (200/month) for €8/month or €80/year. Upgrade from Settings or the pricing page.

Wednesday, February 18, 2026

  • Fixed running race simulation and race pace workouts rendering as "0w" in Intervals.icu — these workouts now correctly use pace-based percentages instead of power percentages, so Intervals.icu can display and execute them properly for runners
  • Fixed AI sometimes generating nested repeat blocks (e.g. "2x" containing "4x") — Intervals.icu silently drops the outer repeat, producing the wrong workout duration; the AI instructions now include explicit examples showing why this breaks workouts and how to write them correctly
  • Fixed running workouts occasionally mixing pace and heart rate targets in the same workout — Intervals.icu can only render one target type per workout, so mixed targets resulted in broken workout structure
  • Fixed swimming workout generation sometimes entering an infinite loop by repeating "Total duration" summary lines — the AI now has explicit instructions to never add summary lines, and any that slip through are automatically stripped
  • Fixed French translations missing accented characters (é, è, ê, à, etc.) throughout the UI — all French locale files now use proper diacritics
  • Fixed post-workout analysis sometimes missing context from the previous week — the activity history window was too short for reliable week-over-week comparisons
  • Ramp workout steps now display as color gradients instead of solid blocks in the workout detail view, making it easier to see how intensity builds across the interval
  • Fixed "Start Training" button on the dashboard navigating to TrainNow instead of opening the planned workout — it now opens the workout detail dialog so you can review and start the workout that was planned for you
  • Fixed training plan projecting too-high weekly TSS in early weeks — the plan now gradually ramps from your current fitness level to the goal instead of targeting peak volume from the start
  • Training plan now detects when you return from illness and automatically reduces the first week back to 55% volume with a recovery focus
  • Improved power profile analysis for ultra-endurance athletes — low sprint and anaerobic power is no longer flagged as a weakness if you have strong 30-60 minute sustained power
  • AI coaching prompts now note that TSB may include planned workout stress, reducing overly cautious fatigue assessments when you have upcoming workouts on the calendar

Tuesday, February 17, 2026

  • Added Training Volume section to the training plan page — see your available vs required weekly hours, a per-day schedule bar chart, and edit your training schedule without leaving the page
  • Fixed CTL goal wizard showing impossibly low max achievable CTL for athletes with limited training history — the ramp rate now has a floor of 2 CTL/week
  • Fixed dashboard showing previous week's training plan data (week type, TSS target, focus) when the current week hadn't been planned yet

Monday, February 16, 2026

  • Fixed weekly plan generating far less training volume than your goal requires — a fatigue-based override was converting Build weeks to Recovery weeks when your TSB was moderately negative, even though your periodization model already schedules recovery weeks; this caused some athletes to get ~250 TSS when they needed 500+
  • Fixed weekly overview in daily email showing "Rest" label for days that have a planned workout name

Sunday, February 15, 2026

  • Fixed goal progress projection overshooting and then declining before race day — the CTL projection now uses your actual periodized weekly TSS targets (accounting for phases, recovery weeks, holidays, and B/C races) instead of a simplified model that could overestimate training load
  • Fixed weekly plan generating too few endurance workouts when strength-only days are configured — strength days were incorrectly consuming your endurance session budget, so 4 strength days with 6 desired sessions would only produce 2 cycling/running workouts instead of the full amount
  • Fixed running workouts using too-low pace zones — endurance runs were targeting 56-75% pace (Z1 territory) instead of 65-80% (Z2), because the workout catalog used cycling power zones for running pace; all running workout types now use sport-specific pace zone ranges
  • Fixed daily workouts uploading to the previous day for users in east-of-UTC timezones (e.g., China, Australia) — the upload date was using the server's UTC date instead of your local date
  • Fixed workout profile chart not matching AI-generated workout steps — the chart was showing a template structure while the actual workout had a different interval layout
  • Fixed recovery and taper weeks getting double-reduced workout targets — the weekly TSS budget already accounts for reduced volume, but each workout was applying the reduction again, resulting in ~49% volume instead of the intended ~70%
  • Training plan now shows your periodization cycle position (e.g., "Week 1 of 4") and week type badges (Recovery, Peak, Taper) so you can see where you are in your mesocycle at a glance

Friday, February 13, 2026

  • Added workout library picker to JustTrain page — browse and select from your IntervalCoach workout library instead of only generating AI workouts, with search filtering and one-tap selection
  • Added support for multi-day goal events (stage races, tours) — the app now recognizes events spanning multiple days from Intervals.icu, extends Race Week phase across the full event duration, shows date ranges in settings, and informs the AI planner about multi-day demands
  • Added manual phase planning option in Goal Setup Wizard — choose between automatic event-based planning or custom Base/Build/Peak/Taper durations with visual preview bars showing your periodization structure
  • Added trail running support — if your goal event is a trail race, ultra, or mountain run, workouts now use heart rate zones instead of pace (since pace varies with terrain), include hill repeats and elevation gain targets, and the AI coaching prompts account for trail-specific demands like technical terrain and high-impact descents
  • Added elevation data tracking — recent activities now capture total elevation gain from Intervals.icu, giving the AI better context for planning workouts that match your terrain
  • Improved training plan race markers — timeline now shows up to 3 race dots per week with "+N more" indicator for weeks with 4+ events, preventing visual clutter on busy training calendars
  • Improved goal setup wizard with clearer radio button selection — choose between Goal Event Mode (automatic periodization) or Manual Planning (custom phase control) with large, accessible cards
  • Added validation for manual phase planning — total phase duration is capped at 52 weeks with clear warning messages and disabled save buttons when limits are exceeded
  • Fixed training plan current week indicator appearing on wrong week — the timeline now correctly shows the "Current" marker on the actual current week instead of using array position, which caused misalignment when weeks don't start at 1
  • Fixed dashboard readiness ring turning gray after page load — the recovery indicator now maintains its color (emerald for peak readiness, green for ready, blue for moderate, orange for easy, amber for recovery-only, purple for rest) throughout the entire loading process instead of flickering from the correct color to gray when extended data loads
  • Fixed HRV4Training recovery scores always showing green — the 1-10 scale normalization now uses your personal baseline instead of hardcoded thresholds, so a bad day for you actually shows as yellow/red even if the absolute number looks high
  • Fixed multi-day event end date off by 1 day — multi-day events like "fietsweekend dag 1" (May 29-31) were showing end date as Saturday May 30 instead of Sunday May 31 because the code used the START date of the last sibling event instead of checking for actual end_date_local fields
  • Fixed CTL ramp rate calculation showing wrong values — the historical ramp rate (used by AI to recommend target CTL) was broken when there were gaps in daily data, sometimes showing 0.1 CTL/week when actual growth was 1.4 CTL/week; now uses date-based lookup to find points exactly 7 days apart over a 90-day window
  • Fixed AI goal analysis showing low-intensity demands for race events — multi-day events with warm-up stages (like "dag 1: parcoursverkenning") were confusing the AI into listing "Aerobic base, Active recovery" as key demands instead of high-intensity racing; the AI now focuses on the hardest stages when analyzing A/B race events

Thursday, February 12, 2026

  • Fixed Garmin/Wahoo workout sync showing intervals without power targets — cycling workouts are now converted to structured Intervals.icu format before upload, ensuring head units display correct power targets for each interval
  • Fixed regenerating weekly plan resetting periodization cycle position — if you were 2 weeks into a 3:1 Build/Recovery cycle and regenerated, the plan would schedule 3 more build weeks before recovery instead of 1; the plan now respects your current position in the periodization cycle
  • Added recommended RPE and feel indicators to post-workout feedback form — after completing a workout, the feedback form now shows the expected RPE range (based on workout stimulus type) and recommended feel (based on your recovery score), helping you calibrate your perceived effort
  • Fixed weekly plan workout durations deviating significantly from configured availability — workouts that are too long or too short (beyond ±10%) are now caught and replaced with correctly-timed templates, so a 2h target won't produce a 2h58m or 1h30m workout
  • Fixed weekly plan assigning unrealistic pure Tempo workouts for long rides — rides over 2.5 hours are now automatically set to Endurance intensity, preventing physiologically impossible sessions like 4 hours of continuous tempo
  • Fixed weekly overview in daily email showing "Rest" for days that have scheduled workouts — today's planned workout now correctly appears in the week overview
  • Fixed post-workout analysis flagging normal heart rates as "quite high" — the AI now knows your LTHR and Max HR from Intervals.icu settings and interprets heart rate relative to your personal thresholds, not absolute values
  • Fixed race day email showing literal backslash-dash characters instead of line breaks in pacing and warmup sections
  • Fixed "Reset Calendar" not clearing existing workouts before regenerating — previously, resetting your plan would create duplicate workouts alongside the old ones instead of replacing them
  • Fixed weekly plan showing "Peak" phase while the dashboard shows "Taper" — near phase boundaries, the weekly plan and training plan timeline were calculating the phase independently from the dashboard, ignoring hysteresis. All surfaces now use the same central phase calculation
  • Fixed dashboard readiness status badge flickering between different labels during page load — the label now shows a loading state until the AI assessment is ready, then displays once with the final result
  • Fixed intermittent crash on Settings page on Mobile Safari caused by a hydration mismatch when swapping the theme picker skeleton for the actual dropdown — the page now waits for full hydration before rendering settings content
  • Fixed intermittent crash on TrainNow page on mobile browsers — simplified tooltip rendering to eliminate cascading state updates during page load that could overflow the call stack on devices with limited memory
  • Fixed stale eFTP used for athletes who train both indoors and outdoors — Intervals.icu maintains separate eFTP models per sport type, so the app now uses whichever was updated most recently instead of always defaulting to outdoor
  • Fixed AI thinking/reasoning text leaking into workout descriptions — internal chain-of-thought like calculation notes and self-corrections are now filtered out before displaying workouts
  • Fixed fitness trend chart showing tomorrow's date for athletes in western timezones — the dashboard now uses your local timezone instead of server UTC time to determine today's date
  • Fixed workout profile chart sometimes showing phantom intervals (e.g., Sweet Spot blocks) that don't exist in the actual workout text — when the AI generates a workout in a format the chart parser can't recognize, the chart is now hidden rather than showing misleading template-based intervals
  • Fixed Sweet Spot and Tempo power targets being 3-5% lower than expected — the wellness-based intensity reduction was incorrectly applied to all zones; it now only reduces threshold (Z4) and above, keeping moderate-intensity targets at their correct values
  • Fixed post-workout analysis overwriting your activity description in Intervals.icu — the IntervalCoach analysis is now appended below your existing notes instead of replacing them, and re-analyses update only the IntervalCoach section

Wednesday, February 11, 2026

  • Added customizable weekly plan delivery time — choose when you receive your Sunday weekly training plan email (8:00–22:00 in your local timezone) from Settings → Notifications
  • Expanded daily email delivery time range — now available from 3:00 AM to 12:00 PM (previously 5:00–9:00 AM) for early risers and late starters
  • Fixed volume jump warning showing incorrect weekly TSS values — the warning was comparing rolling 7-day windows instead of calendar weeks (Mon–Sun), causing values like "146 TSS" to display when the actual week had 396 TSS
  • Fixed workout structure showing "undefined% FTP" for warmup/cooldown ramp segments — when the Intervals.icu API doesn't provide power data for ramps, the power range (e.g., "40-75%") is now extracted from the step text
  • Fixed zone progression focus areas sometimes labeling stable zones instead of declining zones — when multiple zones had the same level, the sort order was arbitrary; declining zones are now consistently prioritized as focus areas via trend-based tiebreaker
  • Fixed progressive overload showing false decline when comparing rides of very different durations — when comparing a long endurance ride (e.g., 4h @ 210W) to a short threshold session (e.g., 1h @ 220W), the power comparison incorrectly showed decline; now uses TSS comparison when durations differ by more than 50%
  • Added rowing activity support — rowing workouts are now properly recognized as endurance activities and analyzed with HR-based metrics instead of being misidentified as running
  • Improved weekly plan duration awareness — workout durations are now capped based on your recent training rhythm per sport, so you won't get a 2-hour swim if you normally swim 30 minutes (allows up to 30% progression above your recent max)

Tuesday, February 10, 2026

  • Added support for multiple training sessions per day — schedule AM/PM splits (e.g., morning cycling + evening running) in Settings → Training, with per-session duration and sport controls
  • Improved weekly plan workout generation — workouts are now generated in parallel for faster plan creation, with post-generation TSS validation that automatically corrects workouts that deviate more than 15% from target
  • Improved weekly plan workout variety — endurance workouts are now capped at 2 per week and same-stimulus penalties are doubled, so you get more varied training across the week
  • Fixed weekly plan TSS distribution creating unrealistic session loads — individual workouts can no longer exceed 60% of your weekly TSS target, workout selection now considers your session TSS budget upfront (selecting Endurance instead of VO2max when the budget is low), and high-intensity workouts are automatically cascaded down the intensity ladder (VO2max → Threshold → Sweet Spot → Tempo → Endurance → Recovery) as a safety net, preventing AI from generating sessions that overshoot by 150%+ and fail to load in Intervals.icu
  • Fixed weekly plan ignoring recovery status — deload, overreaching, ramp rate, and volume jump warnings now flow into the AI prompt so your plan adapts to your current fatigue
  • Fixed weekly plan swimming workout duration and load estimation — structured swim formats (e.g. "4x100m Z3 Pace") and section headers with repeats (e.g. "Main Set Tempo 6x") are now parsed correctly
  • Fixed goal event distance formatting in AI analysis — distances with many decimal places (e.g., 20.356789 km from Intervals.icu) are now rounded to 1 decimal place (20.4 km) to prevent confusion in AI prompts and ensure consistent formatting
  • Fixed fitness trend chart showing no data for HRV-only users — users who track HRV (heart rate variability) but have no training load data (CTL/ATL) now see their HRV trend instead of an empty chart
  • Fixed TrainNow suggesting wrong phase workouts during taper weeks — when a weekly plan exists, TrainNow now uses the plan's current phase (e.g., Taper) instead of calculating independently, preventing mismatches where the plan shows Taper but TrainNow suggests Build-phase Sweet Spot sessions
  • Added Chinese (Simplified) language support — 中文(简体)now available with sport-specific cycling and running terminology
  • Added Danish language support — Dansk now available

Sunday, February 8, 2026

  • Fixed race-day detection for athletes in positive UTC timezones (e.g. Australia) — activity analysis emails were treating race day as "tomorrow" because the server used UTC instead of the athlete's local timezone, resulting in pre-race tips instead of post-race analysis
  • Fixed several additional timezone bugs found by improved linting: calendar goal countdown could be off by a day, taper recommendations used wrong race date, training gap detection compared UTC vs local dates, and weekly plan event grouping could place events in the wrong week
  • Fixed AI Coach showing all sessions completed when only one of multiple daily sessions is done — on multi-session days (e.g. Strength + Run), completing just one session no longer triggers "training done for the day" messaging

Saturday, February 7, 2026

  • Fixed fitness card on Analytics showing wrong CTL value for users in western timezones — the summary card was not accounting for timezone, causing a large discrepancy with the chart below it
  • Fixed Goal Progress card showing different status on Dashboard vs Analytics — the Dashboard was using a generic growth assumption instead of your actual training progression rate, leading to contradictory "Ahead of Schedule" vs "At Risk" assessments
  • Fixed goal event distance displayed incorrectly — distances from Intervals.icu were shown in meters instead of kilometers (e.g., "1700000 km" instead of "1700 km"), which also caused the AI to misinterpret event demands
  • Fixed Training Stimulus card showing 0 intensity sessions — workouts like "Threshold 4x2km" with warmup/cooldown that diluted zone data were not being classified correctly
  • Fixed HRV data not displaying for Apple Watch users — Apple Watch via Health Sync writes HRV to a different field (SDNN) that was not being read
  • Fixed analytics charts showing tomorrow's date for users in western timezones — the server was using UTC which is ahead of US/Americas timezones
  • Fixed weekly plan running workouts ignoring heart rate-based intensity preference — if you chose HR zones in Settings, running workouts still showed pace targets instead
  • Fixed AI coaching advice using inflated fatigue from planned workouts — TSB is now computed from completed activities only, so rest day recommendations and readiness assessments reflect your actual training load

Friday, February 6, 2026

  • New Training Plan page (beta) — see your full training plan from now to your goal event with week-by-week TSS targets, training phases, CTL projection chart, phase roadmap, and progress tracking. Currently in limited beta availability.
  • Added Plan Progress summary to Training Plan page — shows weeks completed, total TSS achieved vs planned, average weekly completion percentage, and how many weeks hit the target
  • B-race periodization now includes a 1-week mini taper — previously B races went straight from Peak to Race Week, now there is a light volume reduction week before the race
  • Fixed gym and strength sessions being treated as cycling workouts — post-workout analysis no longer compares gym metrics against cycling power expectations, and completing a gym session no longer claims your scheduled bike workout is done
  • Fixed goal event misclassification — the AI now receives distance, duration, and expected load from Intervals.icu when analyzing your goal event, so ultra-endurance and multi-day races are classified correctly instead of being guessed from the name alone
  • Fixed AI coaching messages using "the athlete" instead of "you" — training insights, readiness assessments, and workout explanations now address you directly
  • Fixed goal analysis ignoring custom coaching instructions — your custom instructions (e.g. "74km XC marathon") are now included when analyzing goal event duration and demands

Thursday, February 5, 2026

  • Added strength training support — select Strength alongside Cycling, Running, and Swimming in Settings → Training to include gym sessions in your weekly plan. Existing strength/gym sessions in your Intervals.icu calendar no longer block endurance workout generation.
  • Added Czech and Slovenian language support — switch languages in Settings → Account
  • Calendar improvements — navigate to past months, larger icons/text for better readability, TSS heat-map backgrounds showing training load intensity, and inline legend to save space
  • Fixed swimming workouts showing pool length as duration — "4x 25m" was being parsed as "4x 25 minutes" instead of "4x 100m" because Intervals.icu interprets "m" as minutes
  • Fixed threshold workouts generating at 75% FTP instead of 95-105% — added explicit power zone guidance for all cycling, running, and swimming workout types
  • Improved settings tab selector visibility on mobile — added clearer border, shadow, and dropdown indicator
  • Fixed aggressive weekly TSS targets for goal-based training — now caps CTL ramp at 6 points/week instead of trying to reach target too quickly
  • Fixed calendar not updating after manually uploading activities to Intervals.icu — calendar cache now refreshes when activities are processed
  • Fixed race pace plan failing to load for some events — improved handling of special characters in AI-generated race strategies
  • Improved race strategy in calendar event details — now uses same full context as race day email (fitness, wellness, phase) for better advice
  • Fixed AI advice treating stale wellness data as current — prompts now indicate when data is from yesterday or older
  • Fixed post-workout analysis for FTP tests — the AI now recognizes test workouts (FTP test, ramp test, time trial) and analyzes Normalized Power and Intensity Factor instead of average power, which was incorrectly lowered by warmup and cooldown
  • Fixed Goal Setup wizard showing stale CTL from months ago — wizard was reading oldest fitness data instead of most recent, causing incorrect AI recommendations and slider ranges

Wednesday, February 4, 2026

  • Added "Sessions per week" slider in training settings — you can now mark all 7 days as available while choosing fewer training sessions (e.g., 5), and the coach automatically spreads them out with rest days in between (max 3 consecutive training days)

Tuesday, February 3, 2026

  • Fixed workout interval blocks being ignored when using multi-set structures — workouts like "2 sets of 6 reps" now correctly create all repetitions instead of only running the inner block once
  • Post-workout emails now include a "How did it feel?" button — tap to rate RPE and feel without logging in, and your feedback syncs directly to Intervals.icu
  • TrainNow options are now AI-ranked based on your full training context — recovery status, upcoming events, weekly plan, and training phase all factor into smarter recommendations with personalized reasons in your language
  • Added cycle week adjustment in periodization settings — if your training cycle is out of sync (e.g., system shows week 1 but you're in recovery week 4), you can now tap the correct week number to realign it
  • Rest days now override scheduled workouts — when rest is needed, the coach removes your planned workout and replaces it with an optional recovery session on your calendar
  • Fixed goal setup wizard showing eFTP instead of your chosen FTP preference — if you use manual FTP, the wizard now correctly shows your tested value as the baseline
  • Fixed weekly plans exceeding your available training hours — workouts now respect your per-day time limits, and the weekly summary email shows a note when your TSS target was adjusted to fit your schedule
  • Fixed workout durations showing 3-4 hours instead of ~90 minutes in Intervals.icu — the AI was mentioning race distances (e.g., "74km") in warmup messages, which Intervals.icu parsed as distance targets
  • Fixed weekly plans repeating the same workout type too often — the coach now limits how many times the same stimulus (e.g., Sweet Spot, Threshold) can appear per week, scaled to your training schedule

Monday, February 2, 2026

  • Daily emails now show a week-at-a-glance schedule with TSS progress, week type (Build/Recovery/Taper), and a Mon-Sun day-by-day view showing completed, current, and upcoming workouts
  • Weekly workout plans now prioritize declining zones — if your VO2max or Threshold zones are dropping, generated workouts will target those areas instead of defaulting to your strongest zones
  • Fixed weekly outlook showing "Build" phase with high TSS during race weeks — A/B race weeks now correctly show as "Race Week" with reduced volume for taper
  • Fixed dashboard coaching note showing workout swap recommendations when the system wouldn't actually swap the workout — the coaching note now only appears when conditions have changed enough to trigger an adaptation
  • Fixed goal progress card and week progress card showing different weekly TSS targets — both now display the same periodized plan target

Sunday, February 1, 2026

  • Warmups and cooldowns now use progressive ramps instead of flat zones — warmups gradually build from easy to target intensity, cooldowns ease back down
  • Fixed timezone handling for athletes outside UTC — daily metrics, wellness data, and sick/injured detection now correctly use your local date instead of UTC
  • Improved AI workout completion recognition when third-party apps (Zwift, MyWhoosh) rename scheduled workouts — coaching messages now correctly acknowledge completed workouts

Saturday, January 31, 2026

  • Added German, Spanish, Italian, French, Polish, and Portuguese language support — switch languages in Settings → Account

Friday, January 30, 2026

  • Fixed remaining workout count in daily emails to reflect actual calendar events instead of weekly schedule settings — deleting a workout from your calendar now correctly updates the count
  • Added expandable examples showing week-by-week training patterns for each periodization model, so you can see how load, recovery, and intensity vary before choosing
  • Changing your planned sports or training availability now prompts you to regenerate your training plan, automatically removing workouts for sports you no longer train
  • Fixed B and C races incorrectly getting A-race taper phases — B races now skip taper (openers only), C events train through with no special phases
  • Fixed training phase timeline showing wrong "now" position for B and C races
  • Improved A-race taper to a 3-week window based on Mujika & Padilla (2003) research

Thursday, January 29, 2026

  • Added plan toggles — you can now pause weekly plan generation and daily adaptation independently in Settings → Goals
  • Added "Adapt all calendar workouts" toggle — opt in to let the AI coach adapt externally-scheduled workouts (from Intervals.icu training plans or manual entries) based on your daily readiness. Races are never modified.
  • Added FTP Goal setting — set a personal FTP target in watts. Your goal FTP drives the Peak Form Progress card on the dashboard and guides your AI coach toward your target (Settings → Goals)
  • Added Custom Coaching Instructions — Pro users can write free-text instructions that the AI coach follows across weekly plans, daily emails, and JustTrain workouts (Settings → Training)
  • Dashboard now detects sick/injured status from your Intervals.icu calendar and shows a rest recommendation banner with adjusted AI coaching notes
  • Extended JustTrain duration slider from 2 hours to 4 hours for long endurance sessions

Wednesday, January 28, 2026

  • Added Goal Setup Wizard - a unified 3-step flow to select your goal event, set CTL target intensity (Conservative/Moderate/Aggressive with AI guidance), and optionally regenerate your training plan
  • Added runner-specific dashboard metrics including Critical Speed progress, D' capacity, and pace zones for running athletes
  • Added primary sport setting to customize which metrics are displayed on the dashboard (auto-detect, cycling, running, or multi-sport)
  • Redesigned workout profile chart with Intervals.icu-style visualization - segments are now time-proportional with zone-colored bars, gradient fills, and interactive tooltips showing segment details on hover
  • Fixed workout chart not matching workout text for running workouts - the parser now correctly reads pace percentages like "75% pace" instead of falling back to defaults
  • Polished JustTrain page design with circular step indicators, smoother animations, and improved visual hierarchy
  • Refreshed Calendar page with branded header, improved month navigation, and polished day cells with better hover states and visual hierarchy
  • Polished Settings page with branded header, refined cards, smoother entrance animations, and improved visual consistency across all tabs
  • Refreshed Dashboard and Analytics pages with branded headers, refined section headers, and consistent card styling across all components

Tuesday, January 27, 2026

  • Added PayPal as a payment option for Pro subscriptions - you can now upgrade using either credit card or PayPal
  • Fixed Dashboard Goal Progress card to display your selected goal event instead of always showing the nearest upcoming event
  • Reorganized Settings with a new Goals tab - goal event, periodization, and weekly plan info are now in their own tab for cleaner navigation
  • Mobile-friendly settings navigation - Settings now uses a dropdown menu on mobile devices instead of cramped tabs
  • Added dietary preference setting - choose between standard, vegetarian, or vegan nutrition recommendations in your workout emails
  • Personalize FTP test scheduling - choose how often to test (4, 6, 8, or 12 weeks) or disable automatic test scheduling entirely
  • Choose your preferred FTP test protocol - Ramp Test, 20-minute test, MyWhoosh, Zwift, or your own custom protocol
  • Smarter training for time-crunched athletes: if you train less than 5 hours per week, the app now prioritizes Sweet Spot and threshold work over long endurance sessions, giving you better training adaptations in limited time
  • Added running workout target preference - choose between pace-based targets, heart rate zone targets, or automatic selection (HR for trails, pace for roads)

Monday, January 26, 2026

  • Added Race Pace Plans for goal events - get AI-generated race day strategies with pacing guidance, warm-up protocols, and scenario-based advice for your A, B, and C priority events (Pro feature)
  • Smart FTP/Ramp test scheduling - training plans now automatically include fitness tests every 4-6 weeks to track your progression and keep zones calibrated
  • Fixed AI Coach and Rest Day widgets showing contradictory recommendations - AI Coach now respects your weekly training plan's scheduled rest days instead of recommending workouts based purely on fitness metrics

Sunday, January 25, 2026

  • Event-specific workout prioritization: training now adapts to your goal race type - criterium riders get more VO2max/sprint work while gran fondo riders get more endurance/tempo work
  • Goal distance and duration from Intervals.icu are now used to classify your event and adjust workout recommendations accordingly
  • Added AI nutrition advice for workouts - get personalized pre-workout, during-workout, and post-workout fueling recommendations based on your workout type, duration, and intensity
  • Nutrition advice appears in daily workout emails, post-workout analysis emails, and the JustTrain interface
  • Carb and protein recommendations scale to your body weight for accurate fueling targets
  • Science-backed recommendations following sports nutrition research (Burke et al. 2011, Jeukendrup 2014, Thomas et al. 2016)
  • All nutrition advice available in both English and Dutch

Saturday, January 24, 2026

  • Added referral program - Pro users can share referral codes and earn a €3 credit when referred users upgrade
  • New option to sync workout analysis to Intervals.icu activity descriptions - your analysis appears in Strava via the sync
  • JustTrain duration slider now shows the selected time above the thumb while dragging
  • Redesigned sport picker with icons for clearer selection
  • Added default activity preference in Settings - your preferred sport is now pre-selected in JustTrain
  • Added back button to navigate between JustTrain steps - easily change your sport or duration selection
  • Upload button is now integrated into the workout card for a cleaner interface
  • Smarter daily emails for unscheduled days: instead of always showing "Rest Day", the email now assesses your readiness and encourages JustTrain when you're ready to train

Friday, January 23, 2026

  • Smart sleep adaptation: all recovery metrics (HRV, resting HR, sleep) now compare to your personal 30-day baseline instead of hardcoded thresholds - if you consistently sleep 6 hours and your body shows good recovery, the app treats that as normal for you
  • Training availability now sets your TARGET workout duration - if you set 2 hours, workouts will aim for 2 hours (except during recovery/taper weeks)
  • Post-workout analysis now compares your workout against similar past workouts - see power trends, HR efficiency changes, and progression insights
  • New workout comparison section in post-workout emails shows how you performed vs. the same workout type from weeks ago
  • Activity detail dialog now displays workout-to-workout comparison with trend indicators for power and heart rate
  • HR:Power coupling analysis detects cardiovascular efficiency improvements or signs of fatigue accumulation
  • Added native-style bottom tab navigation for mobile with quick access to Dashboard, Train, Calendar, Analytics, and More
  • Fixed Training Stimulus card showing zeros for high-intensity interval workouts and races by using zone data instead of averaged Intensity Factor
  • Fixed Analytics showing false "No VO2max work" warnings for users with interval workouts
  • Added theme toggle to switch between light mode, dark mode, and system preference
  • Enhanced marketing page with parallax hero, floating orbs, animated stats with icons, and scroll-triggered reveals

Thursday, January 22, 2026

  • Weekly plan workouts now adapt to your daily readiness - threshold becomes endurance when you need recovery, maintaining progression while respecting your body
  • Adaptation reasons are more specific - see exactly why workouts change with details like "Threshold → endurance due to moderate fatigue (TSB -7) and good recovery (82%)"
  • New adaptation section in daily emails clearly shows when and why workouts were adjusted from your weekly plan
  • Workout names are now consistent between JustTrain and daily emails (no more date confusion)
  • Multiple workouts on the same day (warmup, race, cooldown) are properly detected and factored into adaptation decisions

Wednesday, January 21, 2026

  • Added Critical Speed (CS) progression chart for runners in Analytics - track your running fitness over time
  • New Best Efforts table shows your recent 42-day bests vs season PRs for key distances (400m to 5K)
  • Added pace preference setting: choose between Critical Speed (adaptive) or manual threshold pace from Intervals.icu
  • Goal sport detection now identifies running, cycling, swimming, and multi-sport events for smarter training recommendations
  • AI coach provides running-specific CTL guidelines for races from 5K to ultramarathons
  • Added race day warmup and cooldown options in JustTrain - get proper pre-race preparation and post-race recovery workouts
  • Improved workout duration accuracy - workouts now stay within 10% of your selected duration instead of varying widely

Tuesday, January 20, 2026

  • Added FTP preference setting: choose between eFTP (default, adapts to current fitness) or manual FTP (your Intervals.icu setting)
  • Redesigned email templates with modern, professional styling and improved visual hierarchy
  • Enhanced weekly summary emails with better training insights and clearer metrics
  • Improved trial emails with accurate Pro feature highlights and clearer free plan comparison
  • Added "Reset Calendar" option in Settings to regenerate your training plan after changing preferences
  • Fixed cadence instructions not being synced to Intervals.icu in cycling workouts
  • Fixed interval workout structure so repeats sync correctly to Intervals.icu (nested sets like 2x4x now work properly)

Monday, January 19, 2026

  • Your coach now learns your preferences over time - workouts that feel harder, recovery patterns, and training habits are remembered and used to personalize future recommendations
  • AI coach can now access your learned preferences during daily workout decisions for smarter training suggestions
  • Fixed trial reminder emails to use appropriate timing based on your trial length
  • Added self-service account deletion in Settings - securely delete your account and all data with confirmation

Sunday, January 18, 2026

  • JustTrain redesigned as a clear 3-step wizard with progress indicator and auto-scroll
  • Touch-friendly workout options with "Top Pick" highlighting and one-tap selection
  • Fixed date display bug that showed workouts one day off for users in certain timezones (EST, CST, PST)
  • Smarter sport selection matches workouts to your typical training patterns from the last 2 weeks
  • Weekly plans now include gradual 10% duration progression when your schedule allows
  • Sport variety balancing prefers underutilized sports to keep your training diverse
  • Smarter recovery scheduling: the day after a race event now automatically gets an easy recovery workout

Saturday, January 17, 2026

  • Sport-specific training days: restrict which sports can be scheduled on each day (e.g., swim only on Wednesdays)
  • Quick pick workout type in JustTrain - select Recovery, Endurance, Tempo, Sweet Spot, Threshold, VO2max, or Sprints to generate a workout instantly
  • Choose your target goal event from your Intervals.icu calendar (A and B races)
  • Option to regenerate your training plan when changing your goal
  • Post-event congratulations email sent the day after your goal event with prompt for next goal
  • AI-powered power profile analysis with goal-specific strengths, weaknesses, and training recommendations
  • AI recovery assessment provides personalized intensity guidance based on HRV, sleep, and baseline deviations
  • Added resting heart rate trend chart to wellness section

Friday, January 16, 2026

  • Added new Analytics page with comprehensive training insights and historical trends
  • View eFTP progression over time with interactive charts
  • Track peak power records (5s, 1min, 5min, 20min) with all-time bests comparison
  • Monitor weekly TSS trends and training volume
  • Weekly power zone distribution shows time spent in each training zone
  • Weekly heart rate zone distribution for HR-based training analysis
  • See HRV trends with Whoop recovery score integration
  • Progressive overload tracking shows improvement across similar workouts
  • AI-powered insights detect training gaps and health warnings
  • Goal alignment shows projected CTL vs target with weekly TSS needed
  • Time range selector to view 7 days, 30 days, 90 days, or full year

Thursday, January 15, 2026

  • Added swimming as a third supported sport with CSS (Critical Swim Speed) based workout generation
  • Added onboarding wizard for new users to set up training preferences and weekly schedule
  • Calendar now shows completed activities on past days with TSS totals and workout details

Wednesday, January 14, 2026

  • Introduced Free and Pro tiers - Free includes 3 AI workouts per month, Pro offers unlimited access
  • New users get a 7-day Pro trial to experience all features
  • Added subscription management in Settings with Stripe integration
  • JustTrain now shows remaining workouts for Free tier users
  • Added /pricing page with plan comparison and upgrade options
  • Expanded pricing page with detailed Pro feature explanations showing the value of adaptive training
  • Weekly planning now creates full detailed workouts (not just placeholders) for your entire week
  • Daily emails now refine weekly workouts based on current recovery, sleep, and fatigue
  • Workouts automatically adapt when your body signals it needs rest or intensity changes
  • Added holiday-aware training planning - automatically adjusts weekly plan around vacations
  • Pre-Holiday Push: build extra fitness before your vacation with 115% TSS target
  • Holiday weeks treated as recovery with reduced TSS target
  • Races during holidays take priority over recovery planning
  • Added visual training plan calendar view with monthly grid display
  • See planned workouts, races, and events color-coded by type
  • View daily TSS targets and next 4 weeks overview
  • Calendar extends multiple months to your goal date
  • Added email preferences to control which types of emails you receive (Daily Briefing, Workout Analysis, Weekly Summary, Monthly Recap)
  • Added contact page for sending feedback, questions, bug reports, and feature requests
  • Added individual pattern recognition - learns your unique performance patterns
  • Identifies your best training days for intensity, endurance, and recovery
  • Discovers effective workout sequences that work for your body
  • Detects personal warning signs before fatigue or illness strikes
  • Pattern insights now inform AI workout recommendations
  • New "Your Patterns" card on dashboard shows discovered insights

Tuesday, January 13, 2026

  • Added outcome-based learning - workout recommendations now personalize based on what actually works for you
  • Unified workout generation - JustTrain and daily emails now use the same AI-powered approach with personalized messages
  • Added training availability settings - configure which days and how much time you have to train
  • Added preferred email delivery time setting - choose when you receive daily workout emails
  • Added workout difficulty feedback loop - avoids repeating workouts that felt too hard
  • Added zone-based workout classification for more accurate training analysis
  • Improved workout type detection using actual power zone distribution
  • Added fatigue cost estimation based on time-in-zone data
  • Added mismatch warnings when activity name differs from actual intensity
  • Added workout visualization charts showing power zones over time

Monday, January 12, 2026

  • Added AI Training Insight with personalized recommendations
  • Added PWA install prompt for mobile app experience

Sunday, January 11, 2026

  • Added zone calibration system for personalized training zones based on test data
  • Added workout alternatives with ranked options for each training session
  • Added AI-driven training phase detection with scientific thresholds
  • Added weekly TSS volume card to dashboard
  • Added CTL/ATL trend arrows to fitness metrics
  • Added color coding to Sleep and Ramp Rate metrics
  • Added Whoop day strain to readiness assessment
  • Added AI-generated personalized readiness messages
  • Added app localization support (English and Dutch)
  • Improved dashboard loading performance with caching
  • Fixed Intervals.icu workout upload

Saturday, January 10, 2026

  • Added 7-day calendar view on dashboard
  • Improved post-workout email with comprehensive analysis
  • Auto-fetch email and timezone from Intervals.icu during login
  • Added admin dashboard for athlete management
  • Added security improvements (token encryption, rate limiting)
  • Improved error monitoring with Sentry integration
  • Fixed calendar event date handling

Friday, January 9, 2026

  • Added This Week's Progress card to dashboard
  • Added training load warnings and alerts
  • Added fitness projection integration
  • Added phase timeline and upcoming workout display
  • Added form trend chart with color coding
  • Added Whoop webhook for real-time workout generation
  • Added email notification settings
  • Improved dashboard layout and organization
  • Fixed form trend chart direction (old to new)