Files
ukmesh/docs/privacy.md
gadgethd 1d243222ef chore(sync): reconcile with production deploy tree — features, docs, plans gitignored
Bring main up to date with the live UKMesh production tree, reconciled
per-file (tree-wins for deployed features; main-wins where main evolved
past the tree's lineage; hand-merges for mixed files). Verified locally
on the deploy host: backend + frontend typechecks, backend unit suite
(543 pass / 0 fail), frontend suite (147 pass / 0 fail), OpenAPI
contract check, frontend production build, scripts typecheck.

Highlights:
- Deployed features land: tags + recent tags, owner public feed,
  Viterbi path prewarm and prior rebuilds, region participation,
  owner packet-sharing JWT scope, pathing docs, README updates.
- Main-side hardening retained: CI RAM steps + smoke cleanup trap,
  hardened scripts, gitleaks/logging rules, stale-MQTT observer
  protections, alert-receiver queue module, health-status refactor
  with tree retention additions (owner_packet_share_deliveries +
  public_feed_deliveries @30d, node_status_samples @30d — matching
  live TimescaleDB policies).
- Credential-generation client close restored on the tree's ownerAccess
  so the operator revocation tool (owner-auth:revoke) keeps working.
- Migrations renumbered to follow main's 058/059 ledger migrations:
  055_public_feed, 060_region_scope_participation,
  061_packet_share_owner_scope_and_jwt; migration-registry test
  assertions updated to the final numbering.
- Planning/report artifacts removed from the repo; local plans/, *.bak*
  patterns gitignored (deploy tree tidied to match).
2026-10-14 01:48:11 +00:00

4.0 KiB

Privacy & data retention

Applies to ukmesh.com / app.ukmesh.com (MeshCore Analytics). UK GDPR + DPA 2018. Contact: ukmesh@proton.me

1. Error diagnostics telemetry

What is stored (per event): kind (error/warning/unhandledrejection/crash), truncated message (≤500 chars) and stack (≤4000 chars), page pathname only (no query string), userAgent, HMAC-hashed source IP. No raw IPs, no account IDs, no cookies, no localStorage in the telemetry path.

Lawful basis — legitimate interest (Art 6(1)(f)). Three-part test:

  • Purpose test: operating a reliable public service requires knowing when client-side failures occur; this telemetry has already root-caused real production crashes (deck.gl/maplibre, worker-file MIME regressions).
  • Necessity test: error capture cannot be tied to a logged-in account (the site has no general auth), so pseudonymous event capture is the minimum effective means; fields are bounded and truncated.
  • Balancing test: data is pseudonymous (hashed IP, no identifiers), kept 30 days, rate-limited (10/min/IP) and sampled (20/hr/source), self-hosted (no third-party processor → no DPA required), no profiling. Individual impact is minimal; service reliability benefit is direct.

Retention: 30 days, enforced by the operational retention loop (DATA_LIFECYCLE_RETENTION_ENABLED=true + DATA_LIFECYCLE_RETENTION_TARGETS). Erasure: individuals cannot be mapped to rows; the retention job IS the erasure mechanism (documented as such).

2. Mesh packet database

The service stores radio traffic observed on the MeshCore network.

Data Retained Rationale
packets — message content + raw bytes + metadata at most 30 days (Timescale chunk policy + bounded exact-row boundary cleanup) network diagnostics; content is not kept long-term
packet_decryptions — full decrypted messages 30 days (operational retention loop) diagnostics only
owner_packet_share_deliveries — validated packet payload and delivery metadata 30 days after terminal delivery (operational retention loop) durable site-to-site delivery and deduplication; retryable rows remain until terminal
packet_paths — path metadata (node IDs, timing, signal, hashes) indefinite, content-stripped raw pathing analytics is the product
multibyte_path_facts, multihop_paths_weekly, path_*_priors — derived path stats indefinite derived, pseudonymous
packet_daily_stats / packet_hourly_stats indefinite anonymous aggregates

Lawful basis — legitimate interest (Art 6(1)(f)).

  • Purpose test: operating and improving the network (pathing, coverage, diagnostics) requires the packet data; the owner portal requires status data.
  • Necessity test: content is deleted after 30 days; long-term retention is limited to path metadata with no message content and no coordinates, which is the minimum needed for pathing analytics.
  • Balancing test: pseudonymous node identifiers only (linkable to an individual solely when a node owner registers in the portal); no content in long-lived tables; no individual profiling; disclosed in the privacy notice.

Design rules (binding):

  • Path/long-lived tables NEVER gain payload, raw_hex, or coordinate columns. Content-bearing tables always have a retention policy.
  • Retained path visibility is derived from the current private-node prefix tables. Stored packet_paths flags are a trigger-maintained cache and are never the authority for a public or derived read.
  • Decryption outputs land only in short-retention tables (30 days).
  • New derived tables get a lifecycle policy at creation.
  • Erasure (Art 17): owner-portal-linked nodes are mappable — node-scoped deletion procedure in the ops playbook (rows by src/rx node id across packets, packet_paths, decryptions, path facts).

3. Cookies

LocalStorage-only choices (cookie consent, theme). No third-party cookies. PECR does not apply to the mesh radio data (not a public electronic communications network).