.Ember
DotEmber icon

DotEmber

.Ember

Last updated 2026-09-10Effective 2026-09-10

This Privacy Policy describes how .Ember (DotEmber) handles your information. It supplements - and does not replace - the NilToDev master Privacy Policy, which covers studio-level matters (the website, hosting, contact) common to every app we ship.

Plain-English summary. .Ember runs entirely on your device. We do not operate servers, do not collect telemetry, and do not see your journal entries, todos, calendar, or timer sessions unless you opt into one of the third-party integrations described below - and even then your data flows directly between your device and that service, never through us.

Overview

.Ember is a local-first productivity app for macOS, iPhone, and iPad. We do not run servers and we do not collect, store, or sell your personal data. Your journal entries, todos, calendar blocks, and timer sessions live as Markdown files in a folder you choose on your own device. This policy calls that folder your vault. .Ember never sees those files unless you opt in to one of the integrations described below.

This policy describes (1) what stays on your device by default, (2) the optional integrations you can enable, and (3) the third-party services those integrations use.

One policy covers all three platforms. Your device below means whichever of them you are reading this about; where the app or the operating system behaves differently on one, this policy names the platform rather than leaving you to work it out.

What stays on your device

By default, .Ember stores everything locally:

  • Vault content - Journal entries, todos, calendar blocks, notebook organization. Stored as Markdown files in a folder you pick during onboarding - the default is a visible DotEmber folder in your iCloud Drive; any local folder works too.
  • App database - A small local SQLite database caches search indexes, timer sessions, and RSS articles (when News is used). This is an accelerator for the local files; the Markdown files are the source of truth.
  • Widget hand-off (iPhone and iPad) - The Home and Lock Screen widgets run in a separate extension that cannot reach your vault, so the two exchange a little through the shared group.com.dotember.app container: the app leaves today’s open todo titles for the widget to draw; a quick add - from a widget, from Siri, or from the Action Button - leaves its text there until the app next opens and files it; and a todo you check off on the widget leaves a note of that completion the same way, until the app next opens and marks it done. Nothing else is kept there, it never leaves the device, and it goes when the app does.
  • Settings - Theme, accent color, language, week-start day, AI master toggle, and similar UI preferences. Stored locally on your device.
  • AI keys - API keys you paste in Settings → AI are stored in the Apple Keychain. They never leave your device except in direct calls to the provider you chose, and are never transmitted to us.
  • OAuth tokens - Google refresh tokens are stored in the Apple Keychain, one item per account. Same scope as AI keys: never transmitted to us.
  • Vault permission - The permission grant for your vault folder (a security-scoped bookmark) is the third and last thing .Ember keeps in the Apple Keychain. It is a path, not a credential, and it never leaves your device.

We do not transmit any of this to a .Ember server. There is no .Ember server.

Optional integrations

Google Calendar, Apple Calendar, RSS feeds, the Markdown folder mirror and the AI features are all off until you turn them on, and can be turned off again at any time from Settings. iCloud is the exception: it follows your Apple account and where your vault lives rather than an in-app switch - see below. When an integration is active, your data flows directly between your device and that service - never through .Ember.

iCloud (iCloud Drive + Apple CloudKit)

.Ember syncs across your devices two ways, both inside your own Apple account:

  • Vault files ride iCloud Drive. This applies whenever the vault folder sits inside iCloud Drive, as the default DotEmber folder does. Point the vault at a folder outside iCloud Drive and the files stay on that device.
  • Structured records go to CloudKit. Timer sessions, notebook metadata, app settings, license state, the News feeds you subscribe to and their read state, and the Markdown folder mirror’s own configuration are stored in your private CloudKit database under container iCloud.com.dotember.app. Your journal, todo and notebook text is not among them - that text travels as files, above.

Only your iCloud account can read either; Apple’s standard iCloud privacy applies. There is no in-app on/off switch - Settings → Sync → iCloud shows status and offers Check now - and the two halves are switched off in different places:

  • Vault files stop leaving the device the moment you point the vault at a folder outside iCloud Drive. That choice is yours at onboarding and changeable afterwards in Settings → Vault.
  • Structured records are not vault-scoped. That store is device-level and mirrors whenever you are signed in, wherever the vault sits, so it is switched off under your Apple ID → iCloud in System Settings (Mac) or Settings (iPhone and iPad), or by signing out of iCloud.

Turning either off does not delete what is already in iCloud; use Apple ID → iCloud → Manage in the same place to remove that.

On iPhone and iPad the app also registers for silent push at launch - that is how CloudKit says a record changed without the app running. The registration goes to Apple, the notification carries none of your content, and the app never reads the device token.

Google Calendar + Tasks

When connected in Settings → Calendar, .Ember reads and writes events on calendars you select via Google’s Calendar REST API, and tasks on task lists you select via Google’s Tasks REST API. Scopes requested (all in the Sensitive tier - .Ember never requests Restricted scopes such as https://www.googleapis.com/auth/calendar):

  • https://www.googleapis.com/auth/calendar.events - read and write events on calendars the user has selected.
  • https://www.googleapis.com/auth/calendar.readonly - enumerate the calendar list and derive the connected account’s primary email for display in the Settings → Calendar account row.
  • https://www.googleapis.com/auth/tasks - read and write tasks on task lists the user has selected.

Multiple Google accounts are supported; each account’s refresh token is stored as an Apple Keychain item under the service com.dotember.app.google-tokens. Events and task lists are cached in the local SQLite. .Ember writes to your Google Calendar or Google Tasks only when you create, edit, complete, or delete an event or task from inside .Ember - every write originates from a deliberate user action; there is no background sync that pushes local changes you didn’t make. Disconnecting an account (Settings → Calendar → Remove on the account row) revokes the local token, deletes that account’s Keychain item, and removes its cached events and tasks.

Apple Calendar (EventKit)

When connected in Settings → Calendar, .Ember reads from and writes to your local Apple Calendar through Apple’s EventKit framework. The system asks you for full Calendar access the first time - on Mac that prompt sits behind the personal-information.calendars entitlement, while iPhone and iPad gate it on the app’s usage description instead - and you can revoke it at any time under Privacy & Security → Calendars in System Settings (Mac) or Settings (iPhone and iPad). All Apple Calendar data stays on your device - EventKit is process-local; nothing is transmitted off the device via this integration. .Ember writes to your Apple Calendar only when you create, edit, or delete an event from inside .Ember. Events are cached in the local SQLite for the same selectable-calendar UX as the Google integration. Removing the Apple account row in Settings clears the cached events; revoking system-level Calendar access additionally blocks future reads/writes.

RSS / News feeds

Feeds you add in News are fetched directly by your device from each publisher’s URL on a 30-minute schedule. .Ember does not proxy or log these requests. Article content is cached locally for the reader view.

BYOK AI (Claude / Gemini / OpenAI)

When AI is enabled (Settings → AI → master switch) and a provider key is configured, .Ember’s AI features call the provider’s API directly from your device. Version 1.0.0 ships two of them, each reachable from its own screen and as an entry in the command palette; free-text palette commands are not in this release. The relevant data sent depends on the feature:

  • Auto-arrange Inbox - Inbox todo titles, your block names, and the last 14 days of completed/scheduled todo titles + block + start time.
  • Daily Brief - RSS article titles + sources + publication dates from your subscribed feeds, plus the titles of articles you have saved to your journal in the last 30 days.

Each provider has its own data-handling policy:

Disabling AI (master toggle off) immediately stops all outbound AI calls and hides every AI surface in the app.

Google API Services User Data Policy compliance

.Ember’s use and transfer of raw or derived user data received from Google Workspace APIs adheres to the Google API Services User Data Policy, including the Limited Use requirements (and the equivalent Workspace API user data developer policy).

Specifically, for the Google Calendar (calendar.events, calendar.readonly) and Google Tasks (tasks) scopes that .Ember requests:

  • Limited use. Data received from Google APIs is used only to provide or improve the user-facing features that the user requested
    • rendering events and tasks on the Todo Calendar grid; creating, editing, completing, and deleting events and tasks the user authored inside .Ember; surfacing per-calendar visibility and color in Settings → Calendar; resolving conflicts when the same event was edited on both sides between syncs.
  • No transfer. .Ember does not transfer Google user data to third parties, except as necessary to provide or improve the user-facing features (which currently is no such transfer at all
    • every API request originates from the user’s device and hits Google’s endpoints directly), or for security purposes (e.g., investigating abuse), or to comply with applicable laws.
  • No advertising. .Ember does not use Google user data - including any inferences derived from it - to serve advertisements, including retargeted, personalized, or interest-based advertising.
  • No human reading. .Ember does not allow humans to read Google user data, except (a) with the user’s explicit consent for specific data, (b) as necessary for security purposes such as investigating abuse, (c) to comply with applicable laws, or (d) for internal operations on data that is aggregated and anonymized, and only in compliance with the Google API Services User Data Policy. As of the Last updated date above, .Ember operates no servers, employs no support staff with access to user accounts, and performs no aggregated or anonymized processing on Google user data - so no Google user data is read by any human on the .Ember side.
  • No AI/ML training, no transfer for training purposes. .Ember does not use Google user data - raw, aggregated, anonymized, or derived - to develop, train, or improve any generalized or foundational machine-learning or artificial-intelligence model, and does not transfer Google user data to any third party for such training purposes. .Ember’s BYOK AI features (Auto-arrange Inbox and Daily Brief) are described in the “BYOK AI” subsection above; in version 1.0.0 those features operate on local app data (Inbox todo titles, block names, and RSS article titles + saved-article titles) and do not include Google Calendar events or Google Tasks data in the AI request body. Should a future release route Google user data into an AI feature, it would do so only as a user-facing feature for that individual user under Limited Use - never for training a generalized model and never via any provider that re-trains on API-tier inputs.

We will continue to adhere to these restrictions as the product evolves; any future change that would alter the Limited Use posture (e.g., introducing a server-side feature that handles Google data, or routing Google user data through an AI feature) will trigger a privacy policy update and a fresh Google OAuth verification before shipping.

Data protection mechanisms

Sensitive data that .Ember handles locally - Google OAuth refresh tokens, BYOK AI API keys, and StoreKit purchase receipts - is protected by the following mechanisms:

  • Encryption at rest. Google refresh tokens and AI API keys are held as Apple Keychain items - services com.dotember.app.google-tokens and com.dotember.app.byok - and are never written to a file in the app’s own storage. Each item is marked kSecAttrAccessibleAfterFirstUnlock, so it is unreadable until the device has been unlocked once after boot. The encryption key is managed by the operating system and never leaves the device. The third Keychain item, the vault folder’s permission grant under com.dotember.app.vault-bookmark, is marked kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly - the same rule, and it is never carried to another device by a backup either.
  • Encryption in transit. All network requests .Ember makes to Google APIs (https://oauth2.googleapis.com, https://www.googleapis.com, https://tasks.googleapis.com) use HTTPS with TLS 1.2 or newer enforced by the platform networking stack (URLSession). Plaintext fallback is impossible: App Transport Security blocks cleartext HTTP by default, and .Ember ships no NSAppTransportSecurity key in either Info.plist - so there is no exception to audit, and no place to add one quietly.
  • Access control. No other app can read those items, and the mechanism behind that differs by platform. On Mac, .Ember runs under the App Sandbox entitlement com.apple.security.app-sandbox = true - required for Mac App Store distribution - and the items are scoped to its signing identity and to the macOS user account that created them. On iPhone and iPad every app is sandboxed by the platform, so there is no such entitlement to declare, and the Keychain is partitioned by the app’s own identifier. Either way the boundary is enforced by the operating-system kernel; circumventing it would require privilege escalation, which is outside .Ember’s threat model and is itself a violation of Apple’s platform policies.
  • No copies. .Ember does not maintain unencrypted copies of these credentials anywhere - not in your vault, not in UserDefaults, not in log files, not in crash reports. Refresh tokens are decrypted into memory only for the duration of a single token-refresh REST call and are released immediately after the call completes.
  • Token revocation paths. Disconnecting a Google account (Settings → Calendar → Remove on the account row) deletes that account’s Keychain item and removes its cached events and tasks from the local database. Users can additionally revoke the OAuth grant directly with Google at myaccount.google.com/permissions; .Ember treats subsequent 401 responses as a revoked grant and re-runs the consent flow.
  • No transmission to NilToDev. None of these credentials, tokens, or any data fetched using them is ever transmitted to a NilToDev server - there is no NilToDev server. The Keychain items are not marked kSecAttrSynchronizable, so they are excluded from iCloud Keychain and do not leave the device they were created on at all - not even into the user’s own iCloud account.

Analytics, tracking, advertising

None. .Ember does not include analytics SDKs, crash-reporting services that link to user identity, advertising trackers, or any other phone-home telemetry. A clean install talks to Apple and nobody else: iCloud Drive and CloudKit inside your own Apple account, the App Store for your licence, and - on iPhone and iPad - the silent push CloudKit uses to announce a change. No other host is contacted until you add a feed, connect a calendar, or turn on AI.

Purchases (Apple App Store)

.Ember 1.0.0 ships with a Free Trial followed by a one-time in-app purchase to continue use beyond the trial period. Purchase processing is handled by Apple - NilToDev does not receive your credit-card number, billing address, or any other payment instrument data; the App Store EULA governs that relationship.

What .Ember handles locally for license validation:

  • StoreKit 2 transaction record. When you purchase, Apple’s StoreKit framework returns a verified transaction object containing an anonymous transaction ID, the product ID, the purchase date, and the current transaction status (purchased / refunded / revoked). .Ember stores this verified record locally so the app knows whether to show paid features.
  • Trial start date. When the Free Trial begins, the start is recorded on the trial’s App Store transaction via StoreKit 2 - tied to your Apple ID and shared across your devices, with no external server involved. The app may cache this state locally for display; the transaction record is the source of truth.

What .Ember does not handle:

  • Your Apple ID email, name, or any other personal Apple-account detail (StoreKit’s verified transaction does not expose these).
  • Any payment instrument (card number, last 4 digits, billing zip, etc.).
  • Any per-user purchase history beyond your own most recent transaction record.

Refund handling is described in the .Ember Terms of Use §9 - refunds are processed by Apple at reportaproblem.apple.com; NilToDev cannot directly issue refunds.

Sale and sharing of personal information

We do not sell or share your personal information in any sense - including the senses contemplated by the California Consumer Privacy Act / California Privacy Rights Act (CCPA/CPRA), the Colorado Privacy Act, or any comparable framework. We do not engage in cross-context behavioral advertising. We do not have a Data Use Choices opt-out mechanism because there is nothing to opt out of.

Accounts, GDPR, CCPA

.Ember has no user account system - no signup, no login, no .Ember-issued user ID. Because we do not collect, store, or process any personal data on our side (with the narrow exceptions documented in “Purchases” above and “Contact” below), data-subject rights under GDPR / UK GDPR / CCPA / Korean PIPA generally have no NilToDev-side data to act upon. Where rights apply to data held by third-party services you opt into (Apple iCloud, Google, Anthropic, OpenAI), exercise them directly with that third party under their own privacy policies.

For completeness, the framework-by-framework rights summary:

Framework Rights How to exercise against NilToDev
GDPR / UK GDPR (Art. 15-22) Access, rectification, erasure, restriction of processing, portability, objection, withdrawal of consent, lodging a complaint with a supervisory authority Email help@niltodev.com. We respond within 30 days. Most rights have no NilToDev-side data to act on (we hold none); we’ll confirm that in writing.
CCPA / CPRA Know, delete, correct, opt out of sale/sharing, limit use of sensitive personal info, non-discrimination Email help@niltodev.com. We do not sell or share, so the opt-out is moot. Most other rights have no NilToDev-side data to act on.
Korean PIPA (Art. 35-37) Access, rectification, deletion, suspension of processing See the dedicated KR PIPA section in the Korean version of this addendum for the full disclosures and procedure.

For the studio-level position on these regimes (Cloudflare Analytics, hosting, contact handling), see the NilToDev master Privacy Policy.

Children

.Ember is not directed at children under 16 (GDPR threshold) or under 13 (COPPA threshold) and we do not knowingly collect data from such children. Age rating: 4+ (App Store).

Data deletion

.Ember writes user data only to (a) your vault folder, (b) the app’s own container, (c) the Apple Keychain, (d) - on iPhone and iPad - the group.com.dotember.app container the widgets share with it, and (e) - when iCloud is active - your iCloud Drive and your private CloudKit database. There is no .Ember-side database to issue an erasure request against.

Inside the vault, deletes are deferred - not immediate. When you delete a journal entry, a notebook page or a whole notebook, or when sync removes a file that has disappeared upstream, the file is moved to {vault}/_trash/ and kept there for 30 days before being hard-removed by the next cleanup pass. This is a recovery window inside your own folder rather than a private one: _trash/ sits at the vault root, so when the vault is inside iCloud Drive - as the default DotEmber folder is - iCloud Drive carries _trash/ along with everything else. .Ember itself keeps it out of the search index and out of the Markdown folder mirror, and no feature reads it except the recovery UI in Settings → Trash. To empty it on demand, use Settings → Trash → Empty trash. A todo is a line inside a day’s file rather than a file of its own, so deleting one edits that file in place and never passes through _trash/.

To remove every trace of .Ember from a Mac:

  1. Quit the app.
  2. Delete the vault folder - the DotEmber folder in your iCloud Drive by default, or wherever you pointed it. This covers your Markdown, _trash/, and the app’s own .app/ settings folder, since all three live inside the vault.
  3. Delete ~/Library/Containers/com.dotember.app/. As a sandboxed Mac App Store app, .Ember keeps its local SQLite caches (search index, timer sessions, cached RSS articles) there rather than in ~/Library/Application Support/. No credentials are stored here.
  4. Delete the Keychain items - removing a Mac app does not. Open Keychain Access, search for com.dotember.app, and delete the entries for com.dotember.app.byok (AI API keys), com.dotember.app.google-tokens (Google refresh tokens) and com.dotember.app.vault-bookmark (the permission to your vault folder).
  5. Delete the app from /Applications/.

On iPhone and iPad, deleting the app does steps 3 to 5 at once: iOS removes the app’s container, the group.com.dotember.app container and the Keychain items it owns along with it. The vault outlives the app there for the same reason it does on a Mac - it is your folder, in iCloud Drive or wherever you pointed it - so delete it where it lives.

To remove iCloud-synced data, also visit Apple ID → iCloud → Manage → .Ember → Delete, in System Settings (Mac) or Settings (iPhone and iPad).

To revoke OAuth access to your Google account, visit myaccount.google.com/permissions.

Changes to this policy

Material changes will be noted in the in-app changelog and in the two dates at the top of this document - Last updated for the day the text changed, Effective for the day it governs. The canonical published copy is this page on niltodev.com.

Contact

Questions: help@niltodev.com


This addendum reflects .Ember 1.0.0 and supersedes any prior version. For studio-level matters not covered here, refer to the NilToDev master Privacy Policy.