Kinoku
Menu

Privacy and data architecture

Your data,
on your terms.

Offline-first means something exact in Kinoku. Your training record lives on your device. There is no account. No training data ever reaches a Kinoku server. Two features can send data out. Both are opt-in, narrow in scope, and kept apart from the core app.

What stays on device

Every field of your training record is stored on the device, in a SQLite database inside Kinoku's app-private storage. That covers:

  • All workouts, sets, reps, RPE, notes, and timestamps
  • All routines, programs, planned workouts, and periodization state
  • All exercises (the 1,100+ that ship with the app, plus every custom one you create)
  • All progress photos, in the app's private photos folder
  • All GPS run tracks, route points, elevation profiles, and HR traces
  • All cycle-aware data: period dates, phase state, symptoms, and predictions
  • All Pulse Score history, wellness logs, and custom metric values
  • All Health Connect data you have imported (it stays on the device; see below)
  • All settings, themes, scenes, preferences, and achievement unlock state
  • Earned reward tier time and activation history

Nothing in this list leaves the device unless you start a backup, export, or share yourself.

Reproductive health is in its own database

Cycle database architecture diagram: kinoku_db (training data) is included in Google Auto Backup; kinoku_cycle_db (reproductive health) is excluded at the file level.
The dual-database split. Training data flows into Auto Backup. Cycle data never leaves the device.

Period dates, cycle phase, symptoms, predictions, basal body temperature, mucus, LH surges, and pregnancy state live in a second database file (kinoku_cycle_db), apart from the main training database (kinoku_db). The split exists for one reason: Android's automatic backup works at the file level, not the row level. Put reproductive data in its own file, and Kinoku can leave that whole file out of Google Auto Backup.

Two XML rule files declare the exclusion (res/xml/data_extraction_rules.xml for Android 12+, res/xml/backup_rules.xml for older versions). A test locks it in and fails the build if the rules ever drift. Google Auto Backup will not carry the cycle database. Neither will the new-device restore flow. Neither will the cloud copies some phone makers still ship. Period data stays where you logged it, on the phone you logged it on, until you choose otherwise.

The same care covers leak paths inside the app. The cycle DAOs are not exposed on the main AppDatabase class. They can be reached only through a single, walled-off injection point. A second test checks that the DAO getters stay off AppDatabase, so any future change that tries to route cycle data through the main path fails CI before merge.

I built this because reproductive health data carries a different risk than training data. A leaked PR for back squat is a bit awkward. A leaked period record can be a legal risk in some places. The setup is a one-time engineering cost that buys a flat guarantee.

Want to keep your cycle data? Take a manual backup yourself. The ZIP backup you start does include the cycle DB. Your backups, your call. Want it gone? Delete the app and the file goes with it. No copy sits on a Kinoku server, because no Kinoku server holds cycle data. No copy sits in Google Drive, because Auto Backup never sees the file.

What leaves, and when

Exactly two features make network calls in the core Kinoku app:

1. Social Bets (opt-in, PRO)

Create or join a Social Bet and Kinoku connects to Firebase (anonymous auth + Firestore) to sync bet state between you and your opponent. The cloud payload is limited to bet data: bet type, progress numbers, timestamps, and opponent ID. Your wider training record is not sent.

Anonymous auth means there is no Kinoku account, no email, and no password. Firebase hands each install a device-scoped token. Never join a bet, and Kinoku makes zero Firestore calls.

Security: Firestore rules block cross-bet access (you can read only the bets you are in). App Check is enforced on client requests. The details are in the firestore.rules file in the Kinoku repository.

2. BYOK LLM (opt-in, on the roadmap)

A planned feature. Power users can add their own OpenAI or Anthropic API key to turn on large-language-model surfaces. Set a key, and the LLM call goes straight from your device to the LLM provider. Kinoku's servers do not relay it.

No key set means no LLM calls. Kinoku never ships a default key. It never routes through a shared endpoint.

Everything else

Diagnostics are opt-in. Turn them on and Firebase may get app interaction events, crash stack traces, performance traces, and a little extra info such as tier, theme, billing product IDs, and rough workout interaction counts. It does not get exercise names, set logs, notes, route coordinates, Health Connect values, cycle data, photos, or contact details.

The website does not track visits with analytics, cookies, pixels, or fingerprinting. Hosting logs may exist for a short time, to handle abuse and operations, but they are not read for product analytics and do not link to the app.

Google Play handles subscription billing. Kinoku asks Play's billing library to check your tier. The billing tokens never reach a Kinoku server.

Backup format and integrity

The Backup & Restore feature makes a single ZIP file. It holds:

  • The full SQLite database (every row of every entity)
  • All progress photos
  • All run GPX data
  • All your preferences and settings
  • A manifest with a SHA-256 checksum for every bundled file
  • A SQLite magic-byte header check

Restore checks the checksums and magic bytes before it touches any app state. A corrupted backup is reported as such, with a message you can act on. A tampered backup is caught, and restore stops.

The ZIP carries across Kinoku versions (it migrates automatically), across devices, and across reinstalls. Email it to yourself, drop it in a cloud drive you pick, or carry it on a USB stick. The file is yours.

Health Connect model

Health Connect is Android's built-in, on-device store for health data. Kinoku reads from it (HRV, sleep, heart rate, steps, weight, body composition) and writes to it (finished workouts and runs).

The key point: Health Connect data stays on your device by default. When Kinoku reads your HRV, that reading came from whatever app wrote it into Health Connect (WHOOP, Garmin Connect, Samsung Health, and the like), not from a cloud call. You pick which data types Kinoku can reach on Android's Health Connect permissions screen.

When Kinoku writes a workout to Health Connect, that workout becomes visible to any other app you have given read access. You control that too. The visibility chain is plain.

Menstruation is the one Health Connect data type Kinoku treats one-way. The manifest declares the READ_MENSTRUATION permission and never the write permission, so Kinoku can import periods you logged elsewhere but cannot write a single row back to Health Connect. One regression test (ManifestHealthPermissionCoherenceTest) keeps the manifest this way. A second test (CycleImportPrivacyTest) checks that imported periods land in the separately-backed-up cycle database, never in the main training database.

Why no accounts

An account system would force Kinoku to:

  • Store login credentials (or lean on OAuth providers who do)
  • Run a server that signs users in
  • Defend that server against a breach
  • Answer data-subject rights requests (GDPR Art. 15, CCPA §1798.100)
  • Decide what to log, where, and for how long

With no account system, all of these failure modes are gone. The safest server is the one that does not exist. Call it "security by absence," a real design choice with real upsides.

The trade-off: no automatic cross-device sync, no social feed, no server-side tuning. If those matter to you, Kinoku is the wrong tool. If they do not, you get a simpler, faster, more private app.

How Kinoku makes money

Google Play subscriptions. Pro and Elite come monthly, yearly, or lifetime. Google Play handles billing, refunds, and regional pricing. Kinoku runs no separate billing setup.

Kinoku does not sell data, because there is no data to sell. Kinoku shows no ads. Kinoku has no affiliate links in the app. The whole revenue stream is subscriptions, and the free tier is built to be full enough to use without paying, if you do not need the depth.

Privacy contact

Questions about how Kinoku handles your data can go to privacy@kinoku.app. The full Privacy Policy is at /legal/privacy.

Kinoku is run by DREAM SOFT DISTRIBUTED EOOD, a Bulgarian EOOD (limited liability company) based in Plovdiv, Bulgaria. GDPR applies. California residents have CCPA rights. Both line up with how Kinoku already works: it collects little, it does not profile, and it does not share. Your GDPR and CCPA rights are easy to meet, because there is almost nothing held to request or delete.