Published in openvibe-contracts v0.114.0 (docs/adr/ADR-021-analytics.md), rendered as is.

ADR-021: Analytics ownership and privacy bounds

Status: Accepted 2026-09-23. Contract now; extraction decision at Wave 22. Amended 2026-09-24: extraction decided (no analytics service; analytics stays per service through openvibe-shared/analytics).

Context and current evidence

Three repositories carry their own analytics_events. Aggregation lives in Tools. No retention bound exists anywhere (baseline D07-D10).

Decision

Alternatives considered

Migration consequences

Each service adds a nightly prune (30 days) and maps its existing events to the contract fields.

Rollback

Pruning is the only destructive step. Export the rollups before enabling it.

Acceptance tests

Amendment 2026-09-24: the extraction decision

Wave 22 asked whether to create an analytics service, "from measured volume". Decision: no analytics service. Analytics stays per service, through the shared module openvibe-shared/analytics (tracker, privacy, retention, schema, prune CLI; Shared ≥ 1.4.0). The ADR-021 privacy rules above apply unchanged: no IP address, precise location or subject id in raw analytics, and at most 30 days of raw events.

Measured volume (production, read-only, 2026-09-24):

One process per service writes this volume into SQLite without strain. No product needs raw events joined across services: the cross-site rollup already lives in Tools and Network. An extra service would add a deploy unit, a network hop on every page view and a second copy of the privacy rules, and would buy nothing measured.

Where the contract lives. The event schema is openvibe-shared/analytics/event.v1.json (docs/schemas/analytics-event.v1.json in OpenVibe.Shared), versioned with the module that writes it. It is not copied into this repository's catalog, because a second copy would drift. The Decision above said "in OpenVibe.Contracts"; this amendment corrects that.

Revisit (a new amendment here) when any of these is measured:

Consumers: Live (server/index.js, server/paths.js), Network (server/analytics/network.js) and the Tools satellites (apps/*/server/index.js) use the module. A new product that wants analytics uses it too, with its own database and the nightly prune.