Why this is powerful
Facet is cookieless and GPC/DNT-respecting, but arbitrary slicing (filter by page × country × device × referrer …) is exactly how "anonymous" analytics quietly re-identifies people. This issue makes Facet the first analytics tool where segmentation carries a formal (ε, δ)-differential-privacy guarantee: every sliced number is answered from noised aggregates against a per-site privacy budget, so no combination of filters can single out a visitor. Privacy-by-math, not by promise.
Architecture sketch
- DP cube: wrap the aggregation layer (
lib/cube.ts + server rollups) so counts/uniques return calibrated noise (Laplace/Gaussian) sized to the query sensitivity; distinct-visitor counts use a DP cardinality sketch (e.g. noised HyperLogLog).
- Budget accounting: a per-site, per-time-window ε ledger (new table + Durable Object) that debits each released query; when the budget is spent, further novel slices return "budget exhausted" instead of leaking. Cache identical queries so re-asking is free.
- Honest UI: every DP number shows a ± confidence interval and a small "DP" chip; thresholds hide k-anonymity-unsafe rows. Surface remaining budget in Settings.
- Modes: a site config toggle for
strict-DP vs exact (self-hosted operators opt in).
Subtasks
Hard parts: composing budget across correlated queries, DP for unbounded-cardinality dimensions (paths/referrers), and keeping the dashboard useful under a finite budget (query caching + smart defaults).
Why this is powerful
Facet is cookieless and GPC/DNT-respecting, but arbitrary slicing (filter by page × country × device × referrer …) is exactly how "anonymous" analytics quietly re-identifies people. This issue makes Facet the first analytics tool where segmentation carries a formal (ε, δ)-differential-privacy guarantee: every sliced number is answered from noised aggregates against a per-site privacy budget, so no combination of filters can single out a visitor. Privacy-by-math, not by promise.
Architecture sketch
lib/cube.ts+ server rollups) so counts/uniques return calibrated noise (Laplace/Gaussian) sized to the query sensitivity; distinct-visitor counts use a DP cardinality sketch (e.g. noised HyperLogLog).strict-DPvsexact(self-hosted operators opt in).Subtasks
Hard parts: composing budget across correlated queries, DP for unbounded-cardinality dimensions (paths/referrers), and keeping the dashboard useful under a finite budget (query caching + smart defaults).