ADR-0015: Offline-first, no network
- Status: Accepted
- Date: 2026-08-11
- Deciders: maintainers
- Related: security.md, docs/PLAY_POLICY.md
Context
The app reads sensitive bank notification text. Any network capability creates a data-leak surface and Play-review risk for a notification-listener app.
Decision
AutoBudget is fully offline-first:
- No app code path performs network I/O — the release manifest does carry network permissions merged from MapLibre (see Amendment), but nothing in the app opens a socket or issues an HTTP request.
- No analytics, no crash-reporting, and no ad or telemetry SDK that phones home.
- All state lives in the on-device SQLCipher DB.
Consequences
- The shipped app has no notification-data upload path: no app code performs a request, and the network permissions present are unused MapLibre manifest entries. This is a code-level guarantee, not a permission-level one.
- Play Data Safety still answers "no data collected" / "not shared" (all processing is on-device); the console disclosure must acknowledge the merged network permissions rather than claim their absence.
- Backup paths are also disabled (see ADR-0010), closing the last off-device copy path.
Amendment (2026-10-19): MapLibre's merged network permissions
org.maplibre.android:android-sdk:13.0.2 — pulled transitively by
maplibre-compose:0.14.0 for ADR-0030's offline basemap — declares
INTERNET, ACCESS_NETWORK_STATE, ACCESS_WIFI_STATE,
ACCESS_COARSE_LOCATION, and ACCESS_FINE_LOCATION in its AAR manifest.
Manifest merger propagates all five into the release manifest; the app declares
no tools:node="remove" rule. The original "no INTERNET permission" claim was
therefore false from the MapLibre upgrade onward.
The behavioural decision is unchanged and this ADR stays Accepted:
- No app code performs an HTTP, socket, tile, style, glyph, or geocoder request. Maps render from the bundled PMTiles overview and user-imported packs (ADR-0030, ADR-0032); style, glyphs, and attribution ship in assets.
- No analytics, crash-reporting, ad, or telemetry SDK is present.
scripts/check-release-permissions.shpins the complete merged permission set from the release APK and fails on any addition, so a later dependency bump cannot silently add a network-dependent SDK.
Play Data Safety: answer "no data collected" / "no data shared"; do not claim the app has no network permission. If Play review asks, explain that MapLibre supplies the declared permissions and the app code never uses them.
Amendment (2026-11-02): maplibre-compose 0.20 runtime permissions
maplibre-compose:0.20.0 no longer pulls org.maplibre.android:android-sdk
directly; its Android OpenGL runtime artifact
(maplibre-compose-runtime-opengl-android) supplies MapLibre Native and merges
INTERNET and ACCESS_NETWORK_STATE. The app's own manifest declares
ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION, and the runtime no longer
declares ACCESS_WIFI_STATE; the release gate pins the complete merged set.
The behavioural decision and the offline guarantee are unchanged.
Alternatives considered
- Optional cloud sync/backup — rejected: scope, privacy risk, Play sensitive-permission scrutiny. The review queue + export/import cover portability.
- Crash reporting — rejected: would need network and would send notification-derived context.