"Will I have my period the week of the wedding?" is a core prediction question the app could not answer. The calendar marked only the next forecast window and stopped browsing one month out, so a textbook-regular user paged forward into blank months. CycleProjection reaches a year. It is a separate type from Prediction, deliberately: a forecast is something the app scores itself on -- the period arrives inside the window or it does not, and PredictionRecord writes down which -- while a projection eleven cycles out is never scored, never learned from, and will have been replaced four times before its date arrives. Separate types mean a projection cannot reach the accuracy figures by accident. Three rules keep it honest, each with a test named after it. Uncertainty grows as sqrt(n), because cycle lengths are near-independent draws: eleven cycles out is about three times as uncertain as one, not eleven times. Real cycles do correlate, so that is the optimistic edge -- which is the second reason the assumption sentence is mandatory. It declines rather than stretching. Past ten days either side a projection stops being an answer, so the projection ends and reports that it ended -- FertilityEstimate's precedent, which already refuses to show a seventeen-day fertile window. The caller can tell "no period due here" from "cannot see this far", and only the second invites her to log more. The assumption is stated, not implied. Any month showing projected marks carries "If your cycles continue as they have, this is the forecast" with the confidence for that distance beside it. A year-ahead date drawn without that is the clearest overstatement this app could make. Cycle 1 is the engine's own forecast copied through unchanged, so the calendar and the Today screen cannot disagree about the next period. The typical cycle length comes from her own history and never a population default -- projecting 29 days for a 35-day user is §3's core defect repeated twelve times over. PROJECTED_PERIOD is its own mark: the same dashed ring as a prediction, thinner and finer. The family resemblance is the message -- still a period, weaker claim -- and it survives greyscale, which an opacity difference would not. Screen readers get the distance in the label, since they cannot see that a square is months away. Browsing now reaches a year; logging still stops at today. ConfidenceRow and readable() move to feature/common and are shared with the Today screen rather than copied. Two of them drifting apart is a screen saying Medium in dots and Low in words. closes #57 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| data | ||
| database | ||
| datastore | ||
| designsystem | ||
| export | ||
| notifications | ||
| security | ||