Skip to content
Privacy and data

Privacy and data

This page describes what the code does today. The published privacy policy is at runink.org/luna-privacy. Counsel review of the policy is still pending before any store submission.

What is stored

Everything Luna keeps about you is written to your own partition of one encrypted store:

WhatWhere it lives
Chat turns (text and voice transcripts), habit events, avatars, training and meal plans, body records, logged setsAppend-only journal streams, one per kind, per account
Long-term memoryA per-account vector index (hybrid vector + keyword search) that recalls earlier conversations
SessionsA session table holding only a SHA-256 hash of each 12-hour session id
Avatar video loops (custom avatars only)The object store’s media area, served through signed, expiring URLs

The store is LUNA’s own store/appfs root. It is encrypted and sealed under a key derived from the platform’s key-encryption key, and kept on Runink’s self-hosted object storage, not a managed cloud database. Your partition is keyed by a hash of your account, not the raw address, because an address is personal data and shouldn’t appear in a storage path.

Who can read it

  • Only you, through your session. Every request is checked against the session table and the allowlist. The data layer takes the account from the verified session and refuses a request that has none. It never falls back to a shared bucket.
  • Only the aspects that need it. Before the model runs, the server decides which of your data goes into the prompt. Your health journal, body records and plans are included only for the trainer and nutritionist. Your “inner context” is included only for counsel, trainer and nutritionist.
  • No third-party AI provider. Chat, vision, speech-to-text, text-to-speech and embeddings all go to Runink’s own services. At startup the server refuses to run if any of those endpoints would carry personal data off the cluster unencrypted.
  • Conversation text is not logged. Server logs don’t contain your messages. The exception is a short excerpt, logged when the prompt-injection scanner flags a transcript, photo reading or plan text. Your email address is logged at sign-in.

Third parties the apps contact

The model side is fully sovereign. The client still reaches a few outside services:

ContactWhat it receivesWhen
Google Sign-InYour identity at sign-inAlways
The device speech recogniser (usually Google’s on Android)Your voiceOnly on the STT fallback path
The device text-to-speech engineThe text of Luna’s repliesEvery spoken reply on native builds, and the fallback on web
OpenStreetMapYour IP address and the map area you viewWhile tracking an activity
GitHub (raw content)Your IP address and which exercise imageWhen exercise images load
Open-MeteoCoordinates coarsened to about 1 kmOnly if you connect local weather (web build)

Health Connect is not on this list. It is on-device, and Luna only reads from it.

Honesty markers you will see

  • “not saved — Luna won’t remember this”: a reply that streamed but couldn’t be written to the journal. The conversation carries on, but that turn won’t be recalled later.
  • “not verified”: a model proposal the judging ladder couldn’t confirm.
  • A dash or “not reported”: a value Luna doesn’t have. It is never shown as zero.

Deletion

There is no in-app delete, and no account-deletion RPC. The journal is append-only. “Changing” a record appends a newer version, and removing a pantry item or clearing your inner context writes a superseding record. Earlier versions stay in the log.

Deletion today is a manual operator action on request, as the privacy policy describes. There is no retention window in the code: records are kept until they are deleted on request. Removing an account from the allowlist revokes all of its sessions immediately, but it doesn’t delete the data.

Known weaknesses

These are disclosed rather than papered over:

  • The app stores its session token and your email in plain app preferences, not the platform keystore.
  • The cluster egress policy that is meant to restrict where the backend can connect does not restrict it in practice today (see Deployment). The “no third-party AI” guarantee rests on the code having no such path, not on the network policy.