§17 and §18. Ovulation is estimated a luteal phase before the PREDICTED next
period rather than counted forwards from the last one — the luteal phase is the
stable half of the cycle, which is why §17 asks for it that way — and the
fertile window opens five days before ovulation and closes one day after,
because sperm survive and the egg does not.
The uncertainty is inherited, not invented. Ovulation is derived from a
predicted date, so it can never be more certain than that prediction.
THE PART THE DEVICE TAUGHT
The first version showed a user one cycle in a fertile window of 8 Aug – 24 Aug.
Seventeen days. Arithmetically honest, and completely useless — over half a
cycle, dressed up as a feature.
So the estimate now returns null past a usable uncertainty, and Today says "Not
enough history to estimate. Log a few more cycles and the app will be able to
estimate ovulation." Three stable cycles later the same user gets 12 Aug – 20
Aug, which is worth reading. Verified in both states on a device.
That is the same shape as PredictionAccuracy refusing figures below three scored
forecasts and CycleInsights withholding an average below two intervals, and it
is now written down in the architecture doc as a rule rather than three
coincidences: the app declines rather than stretches.
§18'S PROHIBITION IS A TYPE, NOT A CONVENTION
FertilityLikelihood has LOWER, HIGHER and UNKNOWN and no fourth value. Somebody
reading "safe" would take a decision on it; the estimate comes from a predicted
date carrying days of uncertainty; and §18 has already promised this is not
contraception. A test asserts no label contains a permission word, so adding one
is a deliberate act with a failing test.
The disclaimer travels with the feature — same screen, same time. A disclaimer
one tab away is a disclaimer nobody read.
ANOTHER GREYSCALE COLLISION
The ovulation star was centred, which put it directly behind the numeral: in
greyscale "18" and the mark merged into one smudge. Ovulation is now the fertile
ring plus a small star low in the cell, which is also semantically right — that
day IS inside the window, and the pair reads as "that window, and this day".
Nine Compose ModifierParameter warnings fixed properly rather than suppressed.
164 tests, all passing. ./gradlew check green, 0 lint errors.
closes#21closes#22closes#23