v1.9.0
·
477 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
Reworks BBT ovulation detection into a single shared "3-over-6" coverline
detector with disturbance rejection, and lands a batch of external-audit
remediations across cycle logic, onboarding privacy copy, import performance,
and accessibility. No database migrations; no breaking changes.
Changed
- BBT ovulation detection unified on a "3-over-6" coverline with disturbance
rejection. One detector (detectBBTShiftFirstHighDay) now drives all three
surfaces — luteal-phase inference, the calendar tentative-ovulation signal, and
the stats BBT chart coverline + marker — which previously disagreed. The
coverline is the max of the six immediately preceding undisturbed recorded
temperatures; a shift is three calendar-consecutive days strictly above it with
the third day ≥ coverline + 0.2 °C; ovulation is dated to the day before the
first elevated day. Readings on days taggedillness/sleep_disruptionare
excluded from the detection series so a fever can neither inflate the coverline
nor confirm a streak (display series unchanged). The chart draws the coverline
only once a shift is confirmed; the accessibility summary gains a no-shift
sentence; all six locales adopt coverline terminology. (#255, #250) - Age group is genuinely optional. A "not specified" option replaces the
silentunder_40onboarding default. (#250) - Import writes days in one batch — a single range read plus one chunked
CreateBatchinstead of lookup-and-insert per day (with a 20k-unique-date load
test), speeding up large restores. (#250)
Fixed
- Settings section navigation stays pinned below the header while scrolling on
desktop (>=640px); on mobile it remains a static top-of-page index. (#252) - A period day with unset flow now reads "not specified" instead of "none",
which had wrongly implied "no bleeding". (#250) - The calendar distinguishes projected (future / auto-filled) period days from
logged facts, which were previously indistinguishable. (#250) - Removed the false "we do not store identity data" onboarding claim in all
six locales — email and display name are stored. (#250) - Accessibility: password-reveal and mobile-menu tap targets raised to 44px; the
prediction disclaimer given a visible accent; the onboarding quick-pick group
labelled. (#250)
Security
- Cloud/IMDS webhook guidance.
docs/notifications.mdnow documents that on a
cloud host an owner-configured webhook URL can reach the instance metadata
endpoint (169.254.169.254) when the private-address gate is off, and
recommendsWEBHOOK_BLOCK_PRIVATE_ADDRESSES=truefor any cloud (non-LAN)
deployment. The delivery envelope already discards the response body (no
exfiltration path); the residual risk is blind internal-network probing by a
co-tenant owner. Runtime behavior and defaults are unchanged. - Startup warning for the exposed webhook combination — the server logs a boot
warning whenREGISTRATION_MODE=openis combined with
WEBHOOK_BLOCK_PRIVATE_ADDRESSES=false, surfacing the multi-owner /
publicly-reachable SSRF exposure. Defaults unchanged. (#250)
Internal
- Oversized files split to cut merge/regression risk (#251, #253); the CLI command
dispatcher and thewebhook setargument parser decomposed below the gocyclo-15
gate (#256). - Test hygiene: onboarding i18n date-field tests collapsed into one table-driven
test with Italian coverage (#257); round-3 mutation sweeps split from six theme
aggregates into per-source files, dropping one duplicate (#258); v1.8.x
mutation-hardening baseline (#246). - A dependency-free route↔OpenAPI contract test and a
checkStyledControle2e
helper centralizing 12force:trueclicks (#250); README contents / Quick-Start
/ digest-pin guidance and.bin/excluded from the Docker build context (#250);
codecov PR-comment noise suppressed (#254); GitHub Actions and npm dev-dependency
bumps (#247, #248).