The plan remembers tomorrow.
The report has a veto on today.
On the fourth of July the morning report told me to run long: 18–22 km. On its own terms it was flawless — readiness 79, HRV 42, eight hours and fourteen minutes of sleep. And yet the advice was wrong. The next day a key mountain session was waiting: four hours, +1500 m, the last big stimulus thirteen days before the race. The system did not know that — and could not, because it only ever sees today.
I corrected it by hand. Instead of the long run I did an easy zone-one shakeout, ten to fourteen kilometres. Not because the report had the numbers wrong — the numbers were right. Because I was holding tomorrow’s session in my head, and not in the app.
That was not a model error. The model lacked information, not judgement. A training plan closes exactly that gap — not as a pretty spreadsheet on the fridge, but as memory about tomorrow, which a single measurement cannot have. That day I was the one holding that memory. The point was for the system to hold it too.
Two layers, one hard contract
Most apps pick a side. Either you get a rigid plan that cannot see you are ill today, or a daily readiness score that cannot see tomorrow holds the most important session of the block. Each fails predictably: the plan alone is deaf, the report alone is blind.
So I separated the two layers and bound them by a contract that is not up for negotiation: the plan holds the structure, readiness holds a veto on the day. The report reads the plan. The plan never reads the report on the fly. A bad Tuesday therefore does not rewrite fourteen weeks.
A bad day does not cancel the plan
Now the piece I have not met anywhere else, and it follows directly from coaching practice. Not every session in a week weighs the same. The long run, the specific block, the key accent — those are protected. Shakeouts, mobility, easy Z1 — those can be sacrificed.
Hence three different answers to a bad day — not one answer on a slider:
- expendable shakeout, mobility, easy Z1 → ease it off and move on
-
protected
long run, specific block, key accent
→ move it a day or two, swap with an expendable one
- does not fit → it is dropped, and the next week does not make it up
- several bad days in a row → a signal about the block, not the day: rebuild it on a gentler skeleton
Each of those branches has its reason.
- An expendable session — the week stays intact and you lose nothing.
- A protected session — and then the answer is not “go lighter”. A watered-down key session combines the drawbacks of both: the fatigue arrives, the stimulus does not. So the session moves a day or two and swaps places with something expendable. If it does not fit, it is dropped. The following week does not make it up, because that jump would break progression.
- Several bad days in a row — that is a signal about the block, not the day. Then I rebuild the block on a gentler skeleton. The goal stays the same; the road to it gets longer.
The error here runs both ways, which is rarely said out loud. Ignoring the signals ends in injury. Timidly cutting every hard session over a slightly raised resting heart rate ends in no fitness at all. That is why the veto runs on thresholds, not on a hunch.
What a plan has to account for
A plan for mountain running has two axes, not one: distance and vertical. It sounds obvious — until you check how many plans treat vertical as a footnote.
Each axis has a ceiling and a floor. The ceiling follows from the demands of the race you are heading to — not from ambition. The floor is set by what your legs have already proved they tolerate.
That floor is not decoration. For a while the vertical axis did not have one — and it was measurable. For an athlete regularly climbing over four thousand metres a week, the plan for a vertical race prescribed seven hundred. It told them to drop more than 80% below what they were already doing. Formally that matched the rule “a fraction of the race vertical”. As coaching — absurd. With the floor in place, the same case returns a figure more than three times higher.
Beyond the axes, the plan guards the things a coach keeps in their head and a spreadsheet loses:
- Waves and down weeks — a recovery week is lighter than the base it follows, and carries no intensity.
- A cap on the long-run jump — the longest session grows against the longest so far in the block, not against last week.
- Stimulus monotony — seven similar days are not a good week, even if the total adds up. I covered it in a separate post.
- The recovery window after a race — tissue needs time after a hard effort, and that window cannot be switched off. It is the one rule with no exception.
- B and C races — a B race gets a micro-taper and its own recovery window; a C race is training and does not disarm the block. A race mid-build is a stepping stone, not a derailment.
Do those rules actually hold? I generated thirty-four plans — from six to thirty-four weeks, across five different goal shapes. Then I checked thirteen independent conditions against them. Eleven passed with not a single violation across all thirty-four plans. Two did not: session consistency drifted outside mountain ultra, and the cap on the long-run jump could still refer to a session many weeks old. One alarm of my own turned out to be false — I was comparing adjacent weeks instead of the whole chain. I did not read the code. I measured the output.
What distance changes
The most common misconception: the longer the distance, the longer the plan. That is not true — at least not in the way it is usually meant.
Block length depends on the GAP between where you are and what the race demands — not on the distance. The textbook tables (160 km ≈ 48 weeks, 100 km ≈ 28, 50 km ≈ 20) are debut plans, counted from a low base. An athlete who has just finished a hundred does not start the next one from zero. Forcing them into forty-eight weeks is as wrong as giving a first-timer twelve.
What does genuinely change with distance:
| Element | Marathon / short mountain | Ultra 50–100 km | Ultra 100 km+ |
|---|---|---|---|
| Taper | 1 week | 1–2 weeks | up to 3 weeks, descending |
| Shape of intensity | short, sharp accents | a mix | long tempo, not intervals |
| Vertical axis | secondary for a flat goal | equal | often the leading one |
| Descents | rarely limiting | real eccentric load | a frequent cause of DNF |
| Night, gut, kit | not applicable | worth rehearsing | a separate skill |
The taper thresholds are not my invention — they come from tables in Training for the Uphill Athlete (House, Johnston, Jornet, 2019). They also match practice: a hundred and sixty kilometres needs a descending taper of about three weeks, not one easy week before the start.
How many A races fit in a season
The popular advice says: one big goal per season. That shortcut can cost you half a year for no reason. In UltraFlow, “how many A races” is not a prohibition but the result of a season feasibility calculation. It weighs the time you have, the distance between you and each goal, the length of the recovery window after the previous race, and whether a specific block fits in between.
For a first-timer aiming at 160 km the answer is “one” — because that one eats the year. For an athlete with a base, three A races in a season can be feasible, and then the system says so instead of repeating the received wisdom. Feasible does not mean optimal, though: with three goals each one gets a shorter specific block, and the calculation shows that cost as a number, not as a warning. If the jump is too big, you get a stepping-stone race suggestion — with a number, not a platitude.
Where I stop
This section is here on purpose, because without it the rest is a brochure.
The week template long fitted a single shape — mountain ultra. For marathon and half-marathon it drifted, badly. I measured it across seven athlete profiles: 84% of weeks broke the consistency between the week header and the sum of its sessions. After the rebuild, 14% remained.
What remains has one cause, and it does not lie in the code. The literature gives doses for running strength and tempo work in absolute terms — so many minutes — and volume limits as percentages. Those two conventions can contradict each other, and resolving that is a coach's call, not a program's. Until then the system says so, instead of sweeping it under the carpet.
It is the same with goal profiles. The engine has one finished shape today — mountain ultra — and it is those rules that build your plan. The rules for skyrace and vertical races are written down, but I have not wired them in yet, so if your goal sits on that shelf you will get a plan built on ultra rules. I am saying so here because I would rather write it plainly than hope nobody notices. Calibration works the same way: when weekly history is missing, I do not invent volume — the plan then rests on what you declared yourself, and it is marked as such.
Test it on your own data — 14 days free
A plan built from your history, not from a template for “the 100 km runner”. The ceiling from your race’s demands, the floor from what your legs have already carried. A daily report allowed to say “not today”, but not allowed to rewrite your block.
14 days free. Card at signup, nothing charged during the trial, cancel any time. Two weeks are enough to see your block and a dozen or so morning verdicts — and that is the only way to judge whether it works for you.