feat(consents): auto-grant data:<provider> on connect; remove agent: consents (ADR-0015)
- integrations.ts: grant data:<provider> on OAuth callback, revoke on disconnect - Backfill migration: INSERT OR IGNORE data:<provider> for all active tokens - Agent manifests: drop agent:<id> from required_consents (momentum, time-of-day, overdue-task, recent-patterns, health-vitals) — per-agent control is a preference - eligibility.ts: update comment to reflect data:-only consent model - test_manifest.py: assert no agent: consents remain in any manifest - migrations.test.ts: backfill idempotency tests for issue #127 - Dockerfile.api: drop --offline flag (fixes ERR_PNPM_NO_OFFLINE_META) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,7 @@ MANIFEST = AgentManifest(
|
||||
},
|
||||
},
|
||||
context_schema=["google-health.steps", "google-health.sleep", "google-health.activity", "google-health.heart_rate"],
|
||||
required_consents=["data:core", "data:google-health", "agent:health-vitals"],
|
||||
required_consents=["data:core", "data:google-health"],
|
||||
output_contract={"type": "snippet", "format": "free_text"},
|
||||
ttl_sec=1800, # refresh every 30 min — health data changes during the day
|
||||
silenced_in_contexts=[],
|
||||
|
||||
@@ -121,7 +121,7 @@ MANIFEST = AgentManifest(
|
||||
},
|
||||
},
|
||||
context_schema=["profile.features"],
|
||||
required_consents=["data:core", "agent:momentum"],
|
||||
required_consents=["data:core"],
|
||||
output_contract={"type": "snippet", "format": "free_text"},
|
||||
ttl_sec=21_600,
|
||||
inferred_params=[
|
||||
|
||||
@@ -70,7 +70,7 @@ MANIFEST = AgentManifest(
|
||||
},
|
||||
},
|
||||
context_schema=["todoist.tasks"],
|
||||
required_consents=["data:core", "data:todoist", "agent:overdue-task"],
|
||||
required_consents=["data:core", "data:todoist"],
|
||||
output_contract={"type": "snippet", "format": "free_text"},
|
||||
ttl_sec=3600,
|
||||
silenced_in_contexts=["vacation"],
|
||||
|
||||
@@ -131,7 +131,7 @@ MANIFEST = AgentManifest(
|
||||
},
|
||||
},
|
||||
context_schema=["tip_feedback", "profile.features"],
|
||||
required_consents=["data:core", "agent:recent-patterns"],
|
||||
required_consents=["data:core"],
|
||||
output_contract={"type": "snippet", "format": "free_text"},
|
||||
ttl_sec=86_400,
|
||||
inferred_params=[
|
||||
|
||||
@@ -45,6 +45,7 @@ def test_manifest_required_fields(agent_id: str):
|
||||
assert isinstance(m.pref_schema, dict) and m.pref_schema.get("type") == "object"
|
||||
assert isinstance(m.required_consents, list) and m.required_consents
|
||||
assert "data:core" in m.required_consents, "every agent should require data:core"
|
||||
assert all(c.startswith("data:") for c in m.required_consents), "only data: consents allowed; agent: consents have been removed"
|
||||
assert m.ttl_sec == get_agent(agent_id).ttl_seconds, "ttl divergence"
|
||||
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ MANIFEST = AgentManifest(
|
||||
},
|
||||
},
|
||||
context_schema=["profile.features"],
|
||||
required_consents=["data:core", "agent:time-of-day"],
|
||||
required_consents=["data:core"],
|
||||
output_contract={"type": "snippet", "format": "free_text"},
|
||||
ttl_sec=900,
|
||||
inferred_params=[
|
||||
|
||||
Reference in New Issue
Block a user