feat(telemetry): Tier-2 opt-in fleet sharing — consent + egress + backfill (ent#12) - #1723
Merged
Conversation
…kfill (ent#12) The opt-IN egress layer on top of Tier-1 (ent#184). Default-OFF, reversible. Gating shape confirmed: OSS-core consent+egress+backfill, enterprise-gated benchmark carrot (the reward). Stacked on the ent#184 OSS branch. Never egresses without consent — TWO independent gates, both re-checked in share_now: the stored `telemetry_sharing_enabled` consent (default-off) AND the config switch `TELEMETRY_SHARING_ENABLED` (honors DO_NOT_TRACK). Either off ⇒ nothing leaves the box. - services/telemetry_sharing_service.py: consent state (system_settings), build_aggregate_payload (anonymized — installation_id + version/edition/ platform/python + coarse enterprise_features + agent/execution COUNTS + Tier-1 activation-funnel counts; NO PII, content, prompts, emails, or agent names), share_now (gated, fail-open, honest 2xx), and a sleeps-first jittered heartbeat (default 24h) that shares when consent is on. Reuses the operator-intake #38 credential-free httpx transport. - Consent-time retroactive backfill: on the off→on transition the router schedules an immediate fire-and-forget backfill over a disclosed window (default 30d) sourced from Tier-1 product_events. - API (routers/settings.py): GET /api/settings/telemetry-sharing (status + inspectable payload_preview — the operator sees EXACTLY what would be sent before consenting) + PUT (admin + human-only, audit-logged, 409 when hard- disabled). feature-flags exposes telemetry_sharing_enabled (observability). - config.py: TELEMETRY_SHARING_ENABLED/URL/INTERVAL_HOURS/BACKFILL_DEFAULT_DAYS. - lifespan: staggered heartbeat start (+9s). - Frontend: value-framed, optional, non-blocking consent ask in the onboarding wizard (hidden when hard-disabled) + a reversible default-off Settings → General panel (TelemetrySharingPanel.vue) with the inspectable payload preview + backfill picker; the gated ActivationFunnelPanel shows the benchmark reciprocity status. - Docs: docs/PRODUCT_EVENTS.md Tier-2 section (payload schema + reversibility + backfill) + requirements §45.1. Tests: tests/unit/test_ent12_telemetry_sharing.py (8) — no-PII payload, both-gate egress, opt-out stops egress, fail-open, non-2xx not marked shared, consent round-trip. Verified live on the Postgres stack: gating + delivery to a local sink + no-PII + reversibility (21 checks), and the router/preview end-to-end. No real external egress in any test. Related to ent#184 (Tier-1) · pairs with trinity-enterprise benchmark carrot. Depends on #1721 (ent#184 OSS) — rebase onto dev when it merges. Related to ent#12 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
vybe
force-pushed
the
feature/ent12-telemetry-sharing
branch
from
July 22, 2026 08:40
f087c16 to
9e5f48d
Compare
|
Resolve by running |
…-all block, wizard disclosure (ent#12)
Validation-pass fixes on the Tier-2 sharing PR:
- AuditEventType.SETTINGS does not exist — the consent audit call raised
AttributeError into the best-effort except and never logged. Use
CONFIGURATION like every sibling settings audit.
- Wire TELEMETRY_SHARING_{ENABLED,URL,INTERVAL_HOURS,BACKFILL_DEFAULT_DAYS}
into both compose backend.environment blocks + .env.example — the documented
hard kill switch was inert in every containerized deploy (#1056 class).
- Block the telemetry_sharing_* key family in the generic settings PUT — the
dedicated route's human-only gate (reject_agent_principal + 409 + audit) was
bypassable by an admin-owned agent-scoped key (trinity-ops-agent#232 class).
- Wizard consent copy now discloses the 30-day backfill (FR-4).
Two regression tests pin the enum and the blocklist.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vybe
approved these changes
Jul 23, 2026
vybe
left a comment
Contributor
There was a problem hiding this comment.
Validated via subagent review: payload is genuinely anonymized (allowlist-filtered, no PII), double gate re-checked at send time, opt-out immediate. Three criticals fixed on the branch (nonexistent audit enum, dead TELEMETRY_SHARING_* compose wiring, generic-PUT consent bypass) + wizard backfill disclosure — all with regression tests, CI green. Residual: per-worker heartbeat dup under --workers 2 (dedupe on installation_id server-side) — follow-up.
vybe
pushed a commit
that referenced
this pull request
Jul 23, 2026
80b1bd7 was stale — it predated the ent#189 telemetry merge (3926e63), so the pin was missing the enterprise half of the #1723 OSS pair. 594b0af additionally carries ent#217 (portal thread titles on subscription OAuth), closing the ent#186 known-limitation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vybe
pushed a commit
that referenced
this pull request
Jul 23, 2026
…ed to 594b0af Recheck findings: #1723 merged (ordering gate cleared); the #1753 pin at 80b1bd7 was stale (missing the ent#189 telemetry merge — the ent#185 class its own checklist warns about) — re-pointed to 594b0af; new PR ent#217 validated and merged, completing the ent#186 portal-titles feature and removing its Known-limitations line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
vybe
added a commit
that referenced
this pull request
Jul 23, 2026
…1753) * chore(enterprise): bump submodule to enterprise-main tip for 0.8.5 Picks up the 0.8.5 enterprise payload: skill-runner module (ent#139 + review fixes: single-slot pin), shared-sessions rooms (ent#169 + enumeration-oracle fix), module-registration isolation (ent#196), portal per-user memory (ent#212), telemetry benchmark surface (ent#12), eval strategy doc (ent#206). Pointer verified at enterprise-main TIP (80b1bd7) per the release rule — a stale pin ships 403s with green CI. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * chore(enterprise): re-point bump to new enterprise-main tip 594b0af 80b1bd7 was stale — it predated the ent#189 telemetry merge (3926e63), so the pin was missing the enterprise half of the #1723 OSS pair. 594b0af additionally carries ent#217 (portal thread titles on subscription OAuth), closing the ent#186 known-limitation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Eugene Vyborov <eugene@beingluminous.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ent#12 — Tier-2 opt-in fleet sharing (OSS consent + egress + backfill)
The opt-in egress layer on top of Tier-1 (ent#184). Default-OFF, reversible. Gating shape confirmed: OSS-core consent+egress+backfill, enterprise-gated benchmark carrot.
Never egresses without consent — two independent gates
Both re-checked in
share_now: the storedtelemetry_sharing_enabledconsent (default-off) AND the config switchTELEMETRY_SHARING_ENABLED(honorsDO_NOT_TRACK). Either off ⇒ nothing leaves the box.What ships
services/telemetry_sharing_service.py— consent state,build_aggregate_payload(anonymized: install id + version/edition/platform/python + coarseenterprise_features+ agent/execution counts + Tier-1 funnel counts; no PII, content, prompts, emails, agent names),share_now(gated, fail-open, honest 2xx), and a sleeps-first jittered heartbeat (default 24h). Reuses the operator-intake Task Actions UI #38 credential-free transport.product_events.GET /api/settings/telemetry-sharing(status + inspectablepayload_preview— see exactly what would be sent before consenting) +PUT(admin + human-only, audit-logged, 409 when hard-disabled). feature-flags exposestelemetry_sharing_enabled.docs/PRODUCT_EVENTS.mdTier-2 section (schema + reversibility + backfill) + requirements §45.1.AC coverage
installation_id(gated view lands with the enterprise PR; hosted percentile service is its own issue)Verification
tests/unit/test_ent12_telemetry_sharing.py(8): no-PII payload, both-gate egress, opt-out stops egress, fail-open, non-2xx not marked shared, consent round-trip. Live on the Postgres stack: gating + delivery to a local sink + no-PII + reversibility (21 checks) + router/preview end-to-end. No real external egress in any test.Related to ent#12 · Tier-1 ent#184 · pairs with trinity-enterprise
feature/12-telemetry-benchmark🤖 Generated with Claude Code