Kinoku
Menu
Pillar article 11 min read Last reviewed April 2026

Reproductive Health Privacy Architecture

Why Kinoku keeps cycle and pregnancy data in a separate database that Google Auto Backup never sees, and how tests keep it that way.

Quickstart

Your reproductive health data in Kinoku lives in its own database file, called kinoku_cycle_db. It is kept apart from the main training database, kinoku_db. The cycle file is left out of Google Auto Backup at the file level, set by XML rules. A test locks that in. And the data is reachable only through one dedicated path that keeps it off the main database.

A backup you start yourself does include the cycle file. Your backup, your call. But Google Auto Backup, the new-device restore, and phone-maker cloud copies all leave it out. The design takes a bit of work to build once. In return, it gives a firm promise about where your period data can go.


Diagram of Kinoku's two databases. The training database goes into Google Auto Backup. The cycle database is left out at the file level by an XML rule.

Why a separate database

Most fitness apps that track reproductive health keep it next to everything else. Same database, same tables, same backup. That was the easy path for Kinoku too. Kinoku does not ship it that way because of one limit in how Android backs up apps.

Android Auto Backup works at the file level, not the row level. When the system backs up an app, it copies the app’s private files in full. There is no way to say “back up this app, but skip the period rows.” The rules in data_extraction_rules.xml take file paths and folders. They do not take row-level rules.

That leaves one honest way to keep reproductive health data out of Google Drive. Put it in its own file. Then leave that file out. Everything else is just a policy: locking the data, an opt-out flag, a promise not to sync it. It is not built into the design. And a policy is the wrong thing to lean on. The real risk here is a court order or a state demand for cloud-stored data.

Kinoku uses a second database for that reason, and only that reason.

What lives in the cycle database

Everything tied to reproductive health:

  • Period start and end dates.
  • Cycle phase, such as follicular, ovulation, luteal, or menstrual.
  • Symptom logs: cramps, mood, flow, and anything else you tag.
  • Basal body temperature. A detector reads the temperature shift to estimate ovulation.
  • Mucus notes and LH surge results.
  • Pregnancy state: test results, due date, and week-by-week progress.
  • Any cycle data used by the Elite Analytics Cycle tab.

Everything about training stays in the main database. Workouts, sets, reps, effort, routines, programs, photos, runs, heart-rate data, Pulse history, and achievements all live in kinoku_db. The two databases never share a row.

How the exclusion is set

Two XML rule files sit in the Android resources folder.

res/xml/data_extraction_rules.xml   (Android 12+, "device-to-device transfer + cloud backup" model)
res/xml/backup_rules.xml             (Android 11 and earlier, the legacy backup model)

Both files contain explicit <exclude> clauses naming the cycle database file:

<!-- data_extraction_rules.xml -->
<data-extraction-rules>
  <cloud-backup>
    <exclude domain="database" path="kinoku_cycle_db" />
    <exclude domain="database" path="kinoku_cycle_db-shm" />
    <exclude domain="database" path="kinoku_cycle_db-wal" />
  </cloud-backup>
</data-extraction-rules>

The -shm and -wal files are helper files that SQLite uses. SQLite spreads one database across these three files when a faster write mode is on, which Room turns on by default. Leaving out only kinoku_cycle_db would still back up the -wal file, which holds recent writes. So all three files have to be left out together.

One detail matters here. The exclusion applies to cloud-backup only. The device-transfer block, used to move to a new phone, does not leave the cycle file out. So if you start a phone-to-phone transfer yourself, your cycle data can come with you. Google Drive cloud backup never sees it. A transfer you control does. That split is on purpose.

How the exclusion stays in place

XML rules are easy to write and just as easy to delete by mistake. A later edit to the backup rules, or a quick “let me clean these up” pass, could drop the exclusion. Nobody might notice until a user reports their period data showing up on a fresh-install phone.

A test prevents that. CycleCloudBackupExclusionTest reads the real XML files at build time and checks three things:

  1. cloud-backup excludes each of kinoku_cycle_db, kinoku_cycle_db-shm, and kinoku_cycle_db-wal
  2. device-transfer does not over-exclude, so a transfer you start still carries the cycle file
  3. The same three exclusions exist in the older backup_rules.xml for Android 11 phones

If anyone deletes a line, renames a file, or breaks the rules, the test fails. So does the build. The exclusion can’t slip away on its own.

Keeping the data apart in code

The XML rules cover the files. The same stance covers the app’s code.

The cycle data tools (CycleDao, PregnancyDao) are not exposed on the main AppDatabase class. They live on a separate CycleDatabase class, with their own providers. The only way to reach cycle data in the app is through that one cycle-only path.

This matters because the wiring that supplies these tools is easy to miss. A future feature, say a period note on the lock screen, could add the cycle tool to its setup. It might then read cycle data into a notice that gets tracked or logged by accident. Keeping the tool off the main database forces every read through the cycle-only path. A test, AppDatabaseDaoSurfaceTest, checks that these tools stay off AppDatabase. So later code can’t add them back by mistake.

Put together: the XML rules keep cycle data from leaking through system backup. The code split keeps it from leaking inside the app.

Health Connect: read-only for periods

Health Connect is Android’s own health data store. Kinoku reads from it (recovery, sleep, heart rate, steps, weight, body composition) and writes to it (finished workouts and runs). For most data, this goes both ways. Kinoku reads what other apps wrote, and writes its own data for other apps to read.

Periods are the one exception. The AndroidManifest.xml asks for read access to menstruation and never asks for write access. So even if some future code tried to write a period to Health Connect, the system would block the call. A test, ManifestHealthPermissionCoherenceTest, checks that the manifest stays this way.

Why read-only? Because Health Connect is shared with every health app you have installed. Writing a period to it is much like sharing it with every fitness app on your phone. That is the exact chain Kinoku is built to avoid. Reading is different. It lets people who track their cycle elsewhere, like Clue, Flo, or Apple Health, bring that history into Kinoku without retyping it. Writing back would undo the whole point of the separate cycle database.

Periods brought in from Health Connect go straight into kinoku_cycle_db, never into the main training database. A second test, CycleImportPrivacyTest, checks this from end to end.

What this looks like in practice

You install Kinoku, log a few periods, and log some workouts. You turn on Google Auto Backup in your system settings. Later you buy a new phone, set it up, and restore from Google Drive.

Your training data comes back: workouts, routines, achievements, all of it.

Your cycle data does not. It is not lost. It is still on the old phone if you haven’t wiped it, and it is in any backup you made yourself. But the cloud restore did not carry it over. You see an empty cycle dashboard and a prompt to import from Health Connect or restore from a backup you made.

If your reaction is “good, that’s what I want,” the design is doing its job. If your reaction is “wait, I want my cycle history,” there is a path. A backup you make yourself does include the cycle database. Kinoku offers it in the normal backup and restore flow on first launch. You choose where that file goes: email, a USB stick, or a cloud drive of your choice. Google Drive’s automatic backup never enters the picture.

Why this matters

Reproductive health data carries a different risk than training data. A leaked PR for back squat is mildly awkward. A leaked period record can be a legal risk in some places. That includes parts of the United States after the 2022 Dobbs decision. The Electronic Frontier Foundation, Mozilla’s Privacy Not Included, and several state attorneys general have flagged cloud-stored period data. They call it a type that needs a built-in safeguard, not a promise.

Kinoku is a small app made by one developer in Bulgaria. A user’s legal risk is not Kinoku’s to solve. But one design choice is Kinoku’s to make. It controls whether the data sits where a court order or a breach can reach it. Kinoku is the only one who can decide to put that data in a separate file in the first place.

That choice was made. The tests guard it. Your cycle data stays where you put it.


Where to verify

You can check everything here in the public Kinoku codebase. The key files:

  • app/src/main/res/xml/data_extraction_rules.xml
  • app/src/main/res/xml/backup_rules.xml
  • app/src/main/java/app/kinoku/data/CycleDatabase.kt
  • app/src/main/java/app/kinoku/data/AppDatabase.kt. Note that it has no cycle data getters.
  • app/src/test/java/app/kinoku/privacy/CycleCloudBackupExclusionTest.kt
  • app/src/test/java/app/kinoku/privacy/ManifestHealthPermissionCoherenceTest.kt
  • app/src/test/java/app/kinoku/privacy/CycleImportPrivacyTest.kt
  • AndroidManifest.xml. Search it for the menstruation read permission.

If any of those names ever change in a way that breaks the rule, a test catches it before it ships.

Want the bigger picture of how Kinoku handles all your training data, not just cycle data? See the Data Sovereignty page or the Offline-First Fitness Tracking article.

Track this in the app

Cycle Tracking & Fertility

Full cycle, fertility, and pregnancy tracking with phase context and training links. Built local-first for privacy.

Related features