The problem
You finish a ride with a file holding a few thousand data points and no good way to look at any of it. The tools that do exist want the file uploaded to someone’s server before they will show you anything.
What I built
Past the replay, it models the wind cost of a result separately from the rider’s actual effort, and plans record attempts against forecasts. The route builder turns any ride into a new mapped 3D route anywhere in the continental United States, pulling public USGS elevation and aerial imagery live in the browser. Nothing is pre-baked.
None of it touches a server:
- Ride files are parsed on the device and never uploaded
- The library lives in IndexedDB, with schema versioning and a transactional route and asset lifecycle
- Parsing and elevation decoding run in Web Workers, on adaptive raster budgets, so the interface stays responsive
- A service worker caches assets for offline use
125 automated tests across 33 files cover the physics model, file parsing, comparison logic, route topology, storage lifecycle, and performance budgets.
What changed
It shipped, and it works for a stranger: a real ride file, no account, no setup, and it runs on a phone.
There are no usage numbers, and I am not going to imply an audience it does not have. What it proves is narrower and still worth something. I took a product from concept to a working public URL alone, covering concept, brand, roadmap, UX, engineering, tests and docs.
It is also the only piece of my work a hiring manager can open. Everything else I have built sits behind an employer’s login.
The pattern
Three decisions here are about the same thing: not letting the app claim more than it actually knows.
The matcher reports its own evidence, returning coverage and monotonicity rather than a bare pass or fail, so a partial match is explainable. The builder checks route length, terrain area and shape before any network request goes out, and explains a refusal in plain language. And recorded results are never overwritten by estimates.

The third decision, on screen. Every recorded time carries its modeled calm-equivalent underneath rather than in place of it, and switching the ranking to modeled numbers is a deliberate act with its own control.
The applied-AI work in this drawer runs on the same rule.