Research notes
Mirai Guide: one survival curve behind every answer
Collapsing three disagreeing shopping orders into a single function of time, so the route, the headline, and the leave time finally agree.
For a while the app computed three different shopping orders from two different notions of difficulty, and showed all of them to the same person for the same cart.
The cart page ordered by a risk scalar. The live headline re-ranked that route. The plan page sorted by a curve quantile and ignored live stock completely - which meant the “leave home by” time was derived from a walk the attendee was never going to take.
Not great.
Why It Split
The root cause is that the two difficulty measures answer different questions.
A risk scalar returns a whole-day number. A curve is a distribution over when. Neither can be derived from the other, so each consumer picked whichever one suited it, and then they drifted apart.
The symptoms all follow from that:
- Stop numbers disagreed between pages for the same cart.
- The live headline hardcoded crowd-aware ordering, so someone who had deliberately switched it off still got it.
- Sold-out stops still consumed walk and queue time in the leave-time model, inflating the whole trip.
The Collapse
Everything now reads one primitive: a per-item survival function over arrival time. Ordering, odds, and timing all consume it.
The direction matters here. A scalar cannot produce a leave time, but a survival function can produce a scalar. So the function is the primitive and the scalar is derived, never the other way around.
I wrote the requirements so a reviewer could reject an implementation that violated one. Two are worth repeating:
- No consumer may call the risk scalar directly for ordering. There is one scoped exception, documented rather than hidden: a server-side route endpoint runs without the curve artifact loaded, so it derives the equivalent linear ramp, and its published ordering is unchanged.
- Behavior without a curve must be bit-identical to before. Curve coverage is partial, so the no-curve path is the common path. The refactor was not allowed to move those numbers.
Now the cart, the live headline, and the plan order the same cart the same way. The departure recommendation is computed for the walk the attendee will actually take. And the crowd-ordering toggle means the same thing everywhere.
The Honest Part of the Record
The plan document keeps the table of what was wrong, because every row names a bug someone could put back.
It also records that one follow-up change deliberately did move numbers - a clamp discontinuity fix, reviewed separately and measured on its own. That was kept out of the refactor instead of being folded in and letting the whole thing be called behavior-preserving.