Governs: what this app protects, secret handling, data at rest, and what leaves
the device
Review trigger: Any new SDK or external service; any new secret; any change to
what is stored, exported, backed up or logged; any change to what
the ads or billing subsystems can see
```
## What this protects, and from whom
The asset is a menstrual and fertility history. It is not valuable to a
generic attacker and it is extremely costly to its owner, which makes the threat
model unusual: **the adversaries are mostly people with physical access to the
phone, and organisations that would like to buy the data.**
| Asset | Where it lives | What it would cost to lose |
| --- | --- | --- |
| Confirmed period dates, spotting, cycle history | Room, app-private storage on the device | the thing the user came here to keep private — inferable pregnancy, contraception use, health conditions |
| Predictions, ovulation and fertility estimates | Room, derived from the above | same class: fertility state is health data even though the app computed it |
| Notification content on the lock screen | Android's notification surface | disclosure to anyone who can see the screen, without unlocking it — the most likely real breach here |
| Play Billing entitlement (`remove_ads_forever`) | Google Play, mirrored in DataStore | low: a wrongly granted ad removal costs money, not privacy |
| Upload keystore and Play service-account JSON | the developer machine, **never this repository** | permanent — a signing key cannot be rotated for an existing app listing |
**The adversary list, plainly:** someone who picks up an unlocked phone; someone
who can see a lock screen; a person with a shared device; an ad or analytics SDK
that collects more than it declares; and a data broker offering money. Not a
nation state — controls sized for one would come at the cost of the offline,
accountless design that makes the rest of this true.
## The promise this document has to hold up
> **We will never sell your personal or health data.**
And the wording that is deliberately *not* promised
([§4](../planning/PRODUCT_PLAN.md)): "no third party ever processes any data."
An ads SDK, Play Billing and the store itself process limited technical
information. The architecture minimises that, declares it accurately in Play's
Data Safety section, and never lets health data reach any of them.
## Data at rest, and what never leaves
- Cycle history is in **app-private storage** — never external or shared
storage, never a world-readable path.
- The app works fully offline for logging, editing, prediction, fertility
estimates, calendar, insights, notification scheduling and app lock. **No
server is involved in producing a prediction**, which is the strongest privacy
control here: data that never leaves cannot be sold, subpoenaed from us, or
breached from a server we do not run.
- **No account is required** for core tracking, so there is no identity to
correlate the history with.
- Biometric/PIN gating protects app launch. Where a secret is needed to back
that, it is Android Keystore-backed — never a value in DataStore.
- **Platform backup is reviewed before the health database is allowed into it.**
An Android auto-backup that silently ships the cycle database to a cloud
account defeats the entire local-first argument, and it is on by default.
Until that review has been done and recorded here, the health database is
excluded from backup.
- **Delete My Data is irreversible after confirmation** and actually deletes —
not a soft flag.
## Third parties
Every row is a decision to send someone else's data somewhere. An empty table is
a good table, and this one gets filled in as each subsystem lands.
| Service | What it receives | Why that is acceptable |
| --- | --- | --- |
| Google Play Billing | purchase token, product id, device Play identity | required to sell anything on Play; carries no cycle data, and none may be put in billing metadata |
| Ads provider *(Batch 07, not yet integrated)* | non-personalized ad request, region consent signal | **no health-derived attribute, ever** — see the boundary below |
| Crash reporting *(not yet decided)* | stack traces | only if raw cycle dates cannot appear in them; otherwise not adopted |
## The advertising boundary
This is the one non-negotiable technical rule in the product
([§34](../planning/PRODUCT_PLAN.md)), so it is stated here as a security control
rather than only as an architecture note:
- Ad code sits behind an `AdProvider` abstraction.
- No health-derived property is ever placed in ad request extras, user
properties, or a callback log line.
- Cycle state is never used for targeting. Non-personalized/contextual is the
default.
- The ads provider is not initialised at all for users who bought Remove Ads,
where practical.
- Every SDK's data collection is audited before each release, against what Data
Safety declares.
Enforced structurally, not remembered: the `ads` module declares no dependency