Live, private alpha

Roen Labs

An adaptive training engine for road runners, from 5 km to the marathon. It checks whether a goal time is realistic, builds the plan to race day, and re-plans after every run, explaining each change.

Role
Founder, self-employed. Designed and built it alone in Python.
When
September 2026 to now
Built with
Python, FastAPI, Postgres (Supabase), Next.js, Modal, Strava API

The problem

Most training plans are written once and then followed. By the third week they no longer match what the runner has actually done: a missed session, a cold, a race that went better than expected. Apps accept any goal time without asking whether it's realistic, and a human coach costs more than most amateur runners will pay.

I'm one of those runners, and I wanted a plan that reacts to what actually happened.

How it works

Roen connects to Strava and reads the runner's history2. Before any plan exists it answers one question honestly: is this goal realistic from where you are now? If it isn't, it says what would need to change first.

  • A plan with phases and rules. Base, build, peak and taper, with hard limits on weekly load, long runs and how hard days are spaced. The limits are enforced by the engine, not suggested.
  • Re-planning after every run. When a run is missed, the volume is dropped rather than squeezed into the following days. When a runner reports pain, the plan opens a 72-hour protected window with lighter load before rebuilding.
  • An explanation for every change. Each adjustment comes with the reason behind it, in plain language.
Roen's rehab panel after a runner reports Achilles pain: three days of capped, easy running and the pain rule for building back
What a sample athlete sees after reporting Achilles pain: three lighter days with caps on every run, and the rule for when the plan can build again.

Why it's built this way

The planner is deterministic: the same inputs always produce the same plan, and every rule can be traced to the code that applies it. A language model reads free text, such as "my calf felt tight today", but it never makes a training decision.

A marathon-pace session in Roen with its reasoning open, citing the athlete's recent training load
A sample session with its reasoning open. Every session can show why it was chosen, based on the athlete's recent training load.

It's the same discipline a good valuation model needs. Assumptions are explicit, the rules can be audited, and the results can be reproduced. When I change a rule, a sweep regenerates 954 plans across every distance and level and shows what moved3.

Where it is now

The engine, API and web app are live, and a small group of runners is using it in a private alpha1. Next are race-day pace projections, fuelling guidance and sending sessions to a watch.

Sources

  1. 1Founder's count of invited athletes, October 2026.
  2. 2Live product.
  3. 3tools/sweep_event_specs.py and the engine's mathematical specification. The repository is private.