Skip to main content
← Map Privacy

Privacy, by design

ARO Field Atlas is being built privacy-first. This page is the plain-language version of what we collect and why. A formal, lawyer-reviewed policy will replace this document before we open user submissions in Phase 2C.

Last updated: 2026-05-04 · Draft, pre-pilot

What we collect today

  • Anonymous, cookieless analytics. We use Cloudflare Web Analytics, which does not set cookies and does not fingerprint visitors. We see aggregate counts (page views, referrers, country). We cannot identify individuals.
  • Theme preference. If you choose Light or Dark, we store that choice in your browser's localStorage on your device only. It never leaves your browser.
  • Anonymous behavioral events. When you interact with key controls (filters, map cards, coverage findings) we record the event name plus up to two bounded dimensions (e.g. a program id or country code). No IP, no callsign, no personal data. See the full list below.

Behavioral events we record

Every event we collect is in this list. We never collect anything outside it. Each event records only the event name and one or two dimensions drawn from a fixed allowlist (program ids, ISO country codes, filter modes, gap rule prefixes, locale codes). Numeric values are counts or scores, never identifiers.

  • map.program.filter (program id, match mode): when you toggle a program filter on the map.
  • map.country.filter (country ISO2): when you change the country filter.
  • map.mode.switched (union or intersection): when you change the match mode.
  • map.card.opened: when you open the map card overlay.
  • map.locale.switched (from locale, to locale): when you change the site language.
  • entity.detail.opened (program, country): when an entity detail page loads.
  • coverage.filter.applied (program, rule prefix): when you arrive at the coverage page with filters active.
  • coverage.finding.opened (rule prefix, program): when you click a coverage finding to open its entity page.
  • clock.popover.opened: when you click the header UTC clock to open its popover.
  • pill.feedback.opened: when you open the experimental-status pill feedback panel.
  • pill.dismissed: when you dismiss the experimental-status pill for 30 days.
  • distance.measurement.started: when you activate the map distance-measurement tool.
  • spot.empty_state.shown (state: tight, partial, all-down): when the live-spots layer is on but no rows match your filters, so we can tell apart filter-induced empties from upstream throttle.
  • roster.open: once per session when you first open the Call Roster drawer.
  • roster.row_click: when you tap a roster row to center the map. The matched callsign is never recorded — only that a click happened.
  • roster.sort (sort: recency, band, distance): when you change the roster sort.
  • psk.personal.toggle (state: on, off): when you toggle the personal-PSK lines (who is hearing me).
  • psk.band_activity.toggle (state: on, off): when you toggle aggregate PSK band activity.
  • solar.strip.opened: once per session when the solar/band-condition strip first appears on the map.
  • solar.strip.click_through: when you tap the strip to open the full /solar readout.
  • entity.needed_only.toggle (state: on, off): when you toggle the Needed-only entity filter. Your callsign is never recorded with this event.
  • entity.needed_only.smart_default_applied (bucket: lt-50, lt-200, gte-200) + entity.needed_only.undo_smart: when the Needed-only filter auto-activates because you have 10+ known activations, and whether you immediately reverse it. Coarse activation-count bucket only, no callsign.
  • net.checkin_cta.clicked (phase: cycle-open, live-now, cycle-late): when you click the in-rail ARO Net check-in pill. Records the cycle phase to measure whether the live slot drives more engagement than the routine window. No callsign.
  • buddy.alerts.toggle (state: on, off): when you toggle buddy-callsign alerts. Your buddy list never leaves your device.
  • buddy.alert.fired: when a buddy callsign is heard on the air. The matched callsign is never recorded — only that a buddy was heard.
  • greyline.toggle (state: on, off): when you toggle the greyline + twilight band overlay.
  • viewport_class (size: phone, tablet, desktop): once per session, the coarse screen-size bucket of your browser at first paint. No pixel width is sent, just the bucket. Lets us tell what share of operators use the map on each form factor without identifying anyone.
  • layers_menu.opened: when you open the floating Layers menu on the map toolbar. Records the menu open itself, not which layer you toggle.
  • priv_events_li_layers_menu_basemap_switched
  • priv_events_li_layers_menu_layer_toggled
  • callsign.onboarding.shown / .set / .guest: a three-step funnel for the first-visit banner that asks for your callsign. Records that the banner was shown, whether you submitted a callsign, or whether you chose Explore as guest. The callsign itself is never sent.

We respect the Do Not Track signal. If your browser sends DNT=1, we record nothing from your session, period. No fetch leaves your browser.

Each page load generates a fresh random session id and we send only its short hash (16 hex characters) as a low-cardinality bucket. The id is held in memory for the lifetime of the page and is never stored in localStorage or a cookie. Reloading the page produces a different hash, so we cannot link your sessions together.

For our editorial independence, conflict-of-interest firewall, and takedown procedure, see Governance.

What we do not collect today

  • No accounts, no passwords, no email addresses.
  • No tracking cookies, no advertising IDs, no third-party trackers.
  • No location data of any kind.
  • No personal data sold or shared with third parties.

What will change as we build

When we add features that require personal data (operator accounts, story submissions, optional location pins, sponsor/partner contact), we will:

  • State exactly what is collected and why, in plain language.
  • Ask for explicit consent before collecting it.
  • Make it easy to view, export, correct, or delete your data, GDPR-aligned, regardless of where you live.
  • Default to opt-in for any feature that exposes your location publicly (operator privacy is non-negotiable; see project NN2).
  • Publish a formal Data Protection Impact Assessment (DPIA) before opening user submissions.

Legal basis (when applicable)

For visitors in the EU/EEA, UK, Switzerland, and similar jurisdictions: we currently process no personal data, so no legal basis is required. When we begin processing, we will rely on legitimate interest for essential operations (e.g., displaying user-submitted content the user chose to publish) and explicit consent for anything beyond that.

Data controller

For the purposes of GDPR and similar laws, the data controller for ARO Field Atlas is:

Santiago Arias Consulting (operating as Doulab)
Switzerland
Maintainer: Luis Santiago, HB9HJU / HI8ILO

Switzerland is outside the EU but its Federal Act on Data Protection (FADP, revised 2023) is closely aligned with GDPR. For EU/EEA visitors, Switzerland is recognized as providing an adequate level of data protection. When ARO begins operating in the EU at meaningful scale, we will additionally appoint and publish an EU representative under GDPR Article 27. Until then, all data-subject requests can be addressed to the data controller above.

Sub-processors

ARO Field Atlas runs entirely on Cloudflare (Pages, Workers, D1, R2, Web Analytics) acting as a data sub-processor. The CDN edge serves requests, the Worker runtime executes server-side code, and the analytics layer aggregates pageview counts without setting cookies. Cloudflare's Customer DPA governs the processing relationship. No other third-party sub-processors are in use today; any future additions (transactional email, error monitoring) will be listed here before they process any visitor data.

Legal basis for processing

The table below lists each processing activity, the data involved, and the legal basis under the Swiss Federal Act on Data Protection (FADP, Art. 6) and the EU General Data Protection Regulation (GDPR, Art. 6).

Processing activityDataLegal basis
Website analytics (Cloudflare Web Analytics)Aggregate page views, referrers, country. No cookies, no PII.Legitimate interest (site improvement, no personal data processed)
Entity registry dataPublic program references (POTA, SOTA, WWFF, etc.)Legitimate interest (public program data aggregation)
Net subscriber callsignAmateur radio callsign provided at subscriptionConsent (explicit opt-in subscription)
Net check-in dataCallsign, grid square, check-in date, operator messageLegitimate interest (operational records for amateur radio net)
Contact form / emailName, email address, message contentConsent (user-initiated communication)

Your rights

Under the GDPR (Articles 15 to 17) and the Swiss FADP, you have the following rights regarding your personal data:

  • Right of access (GDPR Art. 15): You may request a copy of any personal data we hold about you.
  • Right to rectification (GDPR Art. 16): You may request that we correct inaccurate or incomplete personal data.
  • Right to erasure (GDPR Art. 17): You may request that we delete your personal data, subject to any legal retention obligations.
  • Right to lodge a complaint: You may lodge a complaint with the Swiss Federal Data Protection and Information Commissioner (FDPIC) or, if you are in the EU/EEA, with your local supervisory authority.

To exercise any of these rights, email [email protected] with the subject line "Data subject request". We will acknowledge your request within 48 hours and respond substantively within 30 days.

Contact

Privacy questions: [email protected], or reach the maintainer via QRZ: HB9HJU.