All Decisions

ADR-0030: Privacy Policy Requirements

DateFebruary 24, 2026
CategoryInfrastructure
Tags
privacy-security

Context

  • Phase 6 (Settings) includes an About screen with "version, privacy policy, credits" and Phase 10 lists "privacy policy finalization" for Play Store release.
  • LocusFlow is architected as a local-first, offline-only app with no network stack (ADR-0002, ADR-0005) and on-device LLM inference (ADR-0021). This is a strong privacy posture, but Google Play Store requires a published privacy policy regardless.
  • The app handles sensitive personal data: reflections (what went well, what didn't, what I learned), personal vision, daily habits, and free-form inbox captures. Even though this data never leaves the device, users need clear, accessible documentation of what is collected and how it is handled.
  • The LLM model download (ADR-0021 §7) is the sole network call the app makes. This must be disclosed.
  • Export files (ADR-0029) may contain sensitive data and are user-initiated, but the privacy policy should address how exported data is treated.
  • Android permissions (if any) must be declared and justified.

Constraints:

  • Google Play Store requires a privacy policy URL at listing time.
  • GDPR, CCPA, and other privacy regulations may apply depending on user location, even for local-only apps.
  • The app has zero telemetry, zero analytics, and zero crash reporting at this stage. If crash reporting is added later (Phase 10), it must respect privacy and be disclosed.
  • The privacy policy must be understandable by non-technical users.

Decision

We will create and maintain a privacy policy that is accessible both in-app (via the About screen in Settings) and at a public URL (for the Play Store listing).

Privacy policy commitments

The privacy policy will clearly state the following commitments:

1. Data collection

Data typeCollected?Stored whereSent anywhere?
Inbox items (tasks, thoughts, notes)YesOn-device (Room DB)No
Processed itemsYesOn-device (Room DB)No
Daily reflections and answersYesOn-device (Room DB)No
Categories, contexts, tagsYesOn-device (Room DB)No
User settings and preferencesYesOn-device (DataStore)No
Feature flag statesYesOn-device (DataStore)No
LLM prompts and outputsGenerated on-deviceIn-memory only (not persisted beyond result)No
LLM model fileDownloaded onceOn-device cacheDownload request to Liquid AI CDN
Device identifiersNoNo
Location dataNoNo
Usage analytics / telemetryNoNo
Crash reportsNo (may change; see §5)No

2. Network access

The app makes exactly one type of network call: downloading the on-device LLM model file (~700 MB) from Liquid AI's content delivery network. This is:

  • User-initiated: the download only starts when the user explicitly requests it.
  • One-time: the model is cached locally and does not require re-download unless the user clears the cache.
  • Content only: no user data, device identifiers, or metadata are sent in the download request beyond the standard HTTP headers the OS includes.

No other network calls are made by the app. All inference runs locally on-device (ADR-0021 §10).

3. Data sharing

The app does not share any user data with third parties. Data export (ADR-0029) is fully user-initiated and user-controlled; the app does not transmit export files.

4. Data retention and deletion

  • All data is stored on-device and persists until the user deletes it.
  • Users can delete individual items through the app's UI.
  • Users can clear all data via the Settings screen's "Clear all data" action.
  • Uninstalling the app removes all stored data (Room DB, DataStore, cached model file).
  • Export files saved to external storage via SAF persist until the user deletes them manually.

5. Future changes

If future versions introduce:

  • Crash reporting: It will be opt-in, privacy-preserving (no user content in reports), and disclosed in an updated privacy policy. The specific tool choice will be made in Phase 10 (ADR candidates list "crash reporting tool selection respecting privacy").
  • Cloud sync: It will be opt-in, end-to-end encrypted, and covered by a new ADR and a privacy policy update (per ADR-0002 follow-up work).
  • Analytics: If ever added, they will be opt-in, anonymous, and clearly disclosed. Current stance: no analytics.

Users will be notified of material privacy policy changes via in-app notice.

6. Children's privacy

The app is not directed at children under 13. No age-gating is implemented; the app collects no data that would trigger COPPA obligations.

7. Permissions

Current Android permissions:

PermissionPurposeRequired?
INTERNETOne-time LLM model downloadYes (for download only)
ACCESS_NETWORK_STATECheck connectivity before downloadYes

No dangerous permissions (camera, microphone, location, contacts) are requested.

Hosting and accessibility

ChannelFormatLocation
In-app (About screen)Rendered Markdown or HTML WebViewBundled in app assets
Play Store listingURLHosted on project website or GitHub Pages
Source repositoryMarkdown filedocs/privacy-policy.md

The in-app version and the hosted version must always be identical in content. The app version string in the About screen helps users verify which version of the policy applies.

Privacy policy structure

The policy document will follow this outline:

  1. Introduction (what LocusFlow is, what this policy covers)
  2. Data we collect (the table above, in plain language)
  3. How we use your data (on-device processing only)
  4. Data sharing (none)
  5. Network access (model download only)
  6. Data export (user-controlled, per ADR-0029)
  7. Data retention and deletion
  8. Security (on-device storage, no encryption yet, planned improvements)
  9. Children's privacy
  10. Changes to this policy
  11. Contact information

Policy maintenance

  • The privacy policy is versioned with a date and a version number.
  • Any material change requires updating all three locations (in-app, hosted URL, repo).
  • Non-material changes (typo fixes, formatting) do not require user notification.

Rationale

  • Transparency despite minimal collection: Even though the app collects almost nothing remotely, documenting what is stored locally builds user trust and differentiates LocusFlow from apps that claim privacy without specifics.
  • Play Store requirement: A privacy policy URL is mandatory for Play Store listing. Better to have a thoughtful one than a boilerplate generator output.
  • In-app accessibility: Users should not need to search the web for the privacy policy. Embedding it in the About screen makes it immediately accessible.
  • Versioned policy: Dating and versioning the policy creates an auditable history and helps users understand what changed.
  • Conservative permission set: Requesting only INTERNET and ACCESS_NETWORK_STATE — and only for model download — keeps the permission footprint minimal and aligned with the zero-network stance.
  • No analytics commitment: Explicitly committing to no analytics in the policy cements the privacy-first philosophy and reduces the temptation to add tracking later without deliberation.

Consequences

  • Positive:

    • Clear, auditable privacy stance that users can verify against app behavior.
    • Play Store listing requirement satisfied from the start of Phase 6.
    • Privacy-first positioning becomes a marketing differentiator.
    • The explicit "no analytics, no telemetry" commitment is a strong trust signal.
    • In-app policy access requires no network, consistent with offline-only philosophy.
  • Downsides:

    • Policy must be maintained across three locations (repo, in-app, hosted URL). Mitigation: ADR-0032 establishes a single-source workflow where docs/privacy-policy.md is the canonical source, CI generates derived artifacts (bundled asset + hosted HTML), and drift is eliminated by design.
    • Any future feature that changes data handling (crash reporting, sync, analytics) requires a policy update and user notification. This is a feature, not a bug — it forces deliberate privacy decisions.
    • Legal review may be needed before public release (Phase 10) to ensure compliance with GDPR, CCPA, and Play Store policies.
  • Follow-up work:

    • Draft the full privacy policy document at docs/privacy-policy.md.
    • Implement the About screen in the Settings feature with version info, privacy policy link, and credits.
    • Set up a hosted URL for the policy (GitHub Pages or project website) before Play Store submission.
    • Revisit the policy when crash reporting is evaluated in Phase 10.
    • Consider adding an in-app "privacy dashboard" that shows data storage size and provides quick access to export and clear data actions.
    • Evaluate whether export files should support optional encryption (user-provided password) as a privacy enhancement.

Alternatives Considered

  • No privacy policy until Phase 10 — Rejected: the Settings screen (Phase 6) already includes an About section, and having a policy ready early demonstrates intentionality. Deferring creates a gap where the app is usable but undocumented on privacy.
  • Boilerplate/generated privacy policy — Rejected: generic policies are vague and often inaccurate. LocusFlow's privacy posture is strong and specific; the policy should reflect that.
  • Privacy policy in-app only (no hosted URL) — Rejected: Play Store requires a URL. Additionally, users may want to review the policy before installing the app.
  • Opt-in consent dialog on first launch — Deferred: since the app collects no data remotely and has no analytics, a consent dialog is not legally required and would add friction to the first-launch experience. If analytics or crash reporting are added later, a consent flow will be needed and should be covered by a future ADR.

Notes

  • The Liquid AI LEAP SDK license (Apache 2.0-based, <$10M revenue) does not impose additional privacy obligations beyond what the model download already entails. No telemetry is sent by the SDK itself during inference.
  • The INTERNET permission cannot be scoped to "model download only" at the OS level. The privacy policy and code architecture (ADR-0005) are the enforcement mechanisms.
  • If the app ever introduces a WebView for displaying the privacy policy, it must not load remote resources — the policy HTML should be bundled as an asset.
  • Consider integrating a "last updated" date in the About screen that pulls from a build-time constant, ensuring users always see the correct policy version.
  • See ADR-0032 for the single-source implementation strategy: CI-generated artifacts, Markdown bundling, HTML deployment, and front-matter versioning.