Why this is powerful
No analytics product can prove its numbers weren't fabricated. Facet already ships a transparency log (mmr_checkpoints/mmr_leaves/mmr_nodes + scitt_log) and a Provenance view. This issue closes the loop: every aggregate the dashboard shows carries a Merkle inclusion proof back to an append-only, publicly auditable log, so a publisher, advertiser, or auditor can independently verify traffic is real — turning "trust me" analytics into verifiable analytics. That is a category-defining differentiator (ad-fraud defense, compliance, publisher payouts).
Architecture sketch
- Commit at ingest: each rollup bucket (site × metric × time-bucket) is hashed into a per-site Merkle Mountain Range; periodic checkpoints are co-signed and appended to the SCITT-style log (extend the existing MMR tables +
apps/server/src/lib).
- Serve proofs: add
/api/stats/proof?bucket=... returning the leaf + audit path + signed tree head. Extend StatsResponse so KPI/series values can be resolved to a ProofRef.
- Independent verifier: a dependency-free
@facet/verify package (browser + CLI) that recomputes the root from a bucket + path and checks the signed tree head — runnable by anyone, no server trust.
- Dashboard: upgrade the Provenance box so a metric shows a "verified" state with a one-click "verify locally in your browser" that runs
@facet/verify.
Subtasks
Hard parts: honest per-bucket commitments without leaking per-visitor data, key management/rotation for the signed tree head, and making verification cheap enough to run client-side. Prior residual noted: rollups are per-hostname-per-bucket while anomalies are per-site aggregates — reconcile the commitment granularity first.
Why this is powerful
No analytics product can prove its numbers weren't fabricated. Facet already ships a transparency log (
mmr_checkpoints/mmr_leaves/mmr_nodes+scitt_log) and a Provenance view. This issue closes the loop: every aggregate the dashboard shows carries a Merkle inclusion proof back to an append-only, publicly auditable log, so a publisher, advertiser, or auditor can independently verify traffic is real — turning "trust me" analytics into verifiable analytics. That is a category-defining differentiator (ad-fraud defense, compliance, publisher payouts).Architecture sketch
apps/server/src/lib)./api/stats/proof?bucket=...returning the leaf + audit path + signed tree head. ExtendStatsResponseso KPI/series values can be resolved to aProofRef.@facet/verifypackage (browser + CLI) that recomputes the root from a bucket + path and checks the signed tree head — runnable by anyone, no server trust.@facet/verify.Subtasks
/api/stats/proof+ProofRefwiring intoTileContext@facet/verify(WASM-free) + CLIHard parts: honest per-bucket commitments without leaking per-visitor data, key management/rotation for the signed tree head, and making verification cheap enough to run client-side. Prior residual noted: rollups are per-hostname-per-bucket while anomalies are per-site aggregates — reconcile the commitment granularity first.