# ADR-0015 — Data-source consents only; drop per-agent consent gate **Date:** 2026-05-11 **Status:** Accepted **Supersedes:** ADR-0014 §3 (consent model) ## Context ADR-0014 introduced `required_consents` on agent manifests. In practice two unrelated concepts were mixed into that field: - `data:` — which data source the agent reads. - `agent:` — whether the user opted into this specific agent. No UI ever granted `agent:` consents, so the eligibility filter at `services/api/src/profile/eligibility.ts` dropped every agent for every real user. The symptom was confirmed by MLflow trace `tr-591449ea8a72af8e81b6a585234a86ab`: user `ODGp4Gkr7JWemMsqcMLMn` had five fresh `agent_outputs` rows but the orchestrator received `agent_ids: []`. ## Decision Collapse to a single consent dimension: **data source**. 1. `required_consents` entries must all start with `data:`. Agent manifests no longer list `agent:` entries. 2. Connecting a data source via the OAuth flow automatically grants `data:` in `user_consents`. Disconnecting sets `revoked_at`. 3. `data:core` continues to be auto-granted on signup. 4. Per-agent control becomes a **preference** (`user_preferences[scope='agent:', key='enabled']`), not a consent. The eligibility filter already honours this — the only change is removing the `agent:*` consent check that was always failing. 5. Eligibility rule (final): an agent is eligible iff every `data:*` it declares is granted and not revoked, no active context is in `silenced_in_contexts`, and the `enabled` preference is not `false`. ## Consequences - Agents that only require `data:core` (time-of-day, momentum, recent-patterns) become eligible immediately after signup. - Agents requiring `data:todoist` or `data:google-health` become eligible as soon as the user connects the integration — no extra consent step. - A backfill migration grants `data:` for every existing active `integration_tokens` row, unblocking users who connected before this change. - `ml/agents/tests/test_manifest.py` asserts all `required_consents` start with `data:`, preventing regression.