Furlong · testing the model over a training block

Sixteen weeks, a full block

Four independent reviews, then a comparison. Three of the four ranked the same thing first, having reasoned from adaptation, from adherence and from published plans: the block reached its ceiling at week seven and held it for nine. The physiotherapist dissented — a plateau is not a safety problem — and asked that fixing it spend none of the guardrails. It did not. The build rate is now 4% a week rather than 7%, blocks consolidate for a fortnight and then restart from the level held, and the longest flat stretch is three weeks instead of nine. Three more, found by reading the plans rather than the code. The block never reset — blockStartKm was set once and carried forward forever, so both runners went flat at week nine and stayed there for the next twenty-three. It was a permanent ceiling wearing the name of a block cap. Every easy day was the same length, so a runner came off a 13.4 km long run into 6.3 km, where every published plan makes the day after the long run the shortest of the week. And the seasoned fixture had its long run on Sunday while the others were on Saturday, which read as the model choosing when it was a test choosing. Twenty-four invariants. A maroon mark under a day is a strength session. Two regressions were found by the ones that had not been asked before. The model had no strength work at all — the rewrite dropped the best-evidenced injury-prevention intervention it had, and no invariant noticed because every invariant was about running. And the mid-week session was called "quality" when it is a longer easy run: the model has no intensity dimension anywhere, and naming a distance as though it were a workout was untrue. Both fixed. The largest remaining gap is that nothing in this model knows anything about sex, which for an injury-prevention app is not a rounding error. Rebuilt after the four-perspective review. The consecutive-day cap is back and checked across the week boundary — the seasoned runner was running six days straight. Every week now carries a mid-week medium-long run at 65% of the long, so the non-long days are no longer interchangeable. The long run takes a share set by how many days there are to spread the rest over, so a three-day beginner gets a run that is actually long. And the block itself is capped at +30%, where it used to climb 71%. A different model. Not the engine in the app — a replacement built from a small piece of state the runner holds, with the week generated from it rather than re-derived each day from the runs it produced. Every week below satisfies eight invariants written before the code: the long run is the longest run and holds its day, the day pattern never moves, building weeks rise at most 10%, the cutback is exactly 20% and applied once, and no profile ends lower than it started. The engine's forward plan assumes every suggestion is taken and re-plans from there. Run it for a hundred and twelve days — the length of a marathon build — and you get the model's own account of what it would do to a runner who does everything right and never gets hurt. Six weeks was not long enough to see the failures: the worst of them only appeared in week eight.

What it shows

It works for the two unconstrained runners: 34 → 47 km and 53 → 68 km over sixteen weeks, a long run every week on the chosen day, down weeks landing cleanly every fourth week. It still fails the two constrained ones — the new runner ends 42% below where they started.


Weekly volume

Four down weeks, at 2, 6, 10 and 14, with the build climbing through them. About +2% a week for the regular runner — at the earlier +2.5% the block compounded to +77%, which no literature supports for a single build.

The anchor — typical distance

Every suggestion is typical × factor. Reading four weeks instead of a season lets the build compound — and for the capped runners, lets it compound downward just as easily, which is the failure still open below.

The progression factor

Held at its ceiling of +9%. A down week is skipped rather than treated as a broken streak, and only overreaching stops a build — being fresh does not.

Four hypotheses, tested

Fixed

The block progresses, and keeps its shape

34 → 47 km for the regular runner, 53 → 68 km for the seasoned one. A long run every week on the chosen day; down weeks at 2, 6, 10 and 14. The long-run share falls from 44% to 37% on its own as volume grows, without needing to be forced down.

Fixed

The long run no longer disappears in week eight

The six-week projection could not see this one. Progression compounds on easy runs, so by week eight typical had climbed to 15 km — the length the long run used to be. Nothing in the last month then cleared the "long enough" threshold, so daysSinceFurlong went nil; nil was being read as zero, meaning "did one today", and the gate's >= 6 never passed again. Weeks 8 to 16 ran without a single long run. Nil now means very overdue, which is what it actually is.

Open — the important one

It detrains the runners it is most trying to protect

The new runner finishes at 7 km a week having started at 12 — down 42%. The 58-year-old drops 15%. Both are the profiles whose distances are capped, and the cap is the cause: when the prescribed run is smaller than the runner's typical session, the typical falls, which shrinks the next prescription, which lowers the typical again.

It is the same self-reference that froze the anchor, running downhill instead of uphill. The guardrails meant to protect beginners and older runners are quietly winding them down instead — which is worse than the flat plan we started with, because it looks like a plan while it happens.

Open

Frequency never grows

Three running days a week for every runner across all sixteen weeks. The days-in-a-row cap is read from the runner's own history, so someone who has never run back-to-back is told never to run back-to-back. The app cannot suggest a fourth day, which is both the best-evidenced way to add volume safely and the real reason the long run is such a large share of the week.