docs+consent: disclose activation analytics honestly across consent modal, privacy policy, and store docs (#81)

The app ships PostHog activation-funnel analytics gated behind the same
consent flag as Sentry, but the consent modal, Settings toggle, privacy
policy, and Play Data safety draft only mentioned crash reporting. Fix
the disclosure everywhere:

- TelemetryConsentModal: body + bullets + a11y labels now cover anonymous
  usage analytics (PostHog EU) alongside crash reports
- Settings: toggle renamed 'Crash Reports & Usage Analytics', description
  names both Sentry and PostHog
- Privacy policy (md + html + live gh-pages mirror): new section 3a with
  the full event/property table, PostHog EU destination, anonymous-ID
  statement, decline/revoke (drop-on-revoke) semantics; sections 4-7, 9
  and the Apple nutrition-label addendum updated for analytics
- play-listing.md: Data safety draft declares App interactions + Device
  or other IDs (opt-in, default OFF, shared with PostHog/Sentry)
- docs/playstore.md: Data safety row flipped to re-verify with pointer
  to the new design record
- docs/analytics.md: new design record — event schema, consent gating
  incl. buffered-event drop on revoke, disclosure surfaces to keep in
  sync, verification checklist (all TODO)
- website privacy page metadata mentions analytics opt-in

Closes #63


Claude-Session: https://claude.ai/code/session_01NJKAQ6HAikWGQK7PGZ5Y4E

Co-authored-by: engineer <engineer@gray-knight-m1.local>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Den
2026-07-17 03:28:00 -07:00
committed by GitHub
parent b52fa52a4c
commit 63f3ec3c7e
10 changed files with 569 additions and 75 deletions

View File

@@ -1,5 +1,9 @@
/**
* First-launch consent modal for Sentry crash reporting.
* First-launch consent modal for crash reporting AND activation analytics.
*
* A single "Allow" decision gates both Sentry (crash reports) and PostHog
* (anonymous usage analytics) — see src/lib/telemetry.ts. There is no
* separate toggle for analytics, so this modal must disclose both.
*
* Shows once when the user hasn't yet made a consent decision.
* Matches the app's existing Settings screen visual conventions.
@@ -33,15 +37,21 @@ export function TelemetryConsentModal({ visible, onAllow, onDecline }: Props) {
{/* Body */}
<Text style={[styles.body, isDark && styles.bodyDark]}>
Share anonymous crash reports to help us find and fix bugs faster. Diagnostic reports
you share are also delivered to our support inbox. No code, prompts, or server
addresses are ever included.
Share anonymous crash reports and usage analytics to help us find and fix bugs
faster. Diagnostic reports you share are also delivered to our support inbox. No
code, prompts, or server addresses are ever included.
</Text>
{/* Detail bullets */}
<View style={styles.bullets}>
<BulletRow icon="checkmark-circle" text="Device model, OS version, app version" isDark={isDark} positive />
<BulletRow icon="checkmark-circle" text="Stack traces of crashes (no variable values)" isDark={isDark} positive />
<BulletRow
icon="checkmark-circle"
text="Anonymous usage events (app opened, connection attempts, messages sent) — sent to PostHog EU"
isDark={isDark}
positive
/>
<BulletRow icon="close-circle" text="Your code, prompts, or chat messages" isDark={isDark} positive={false} />
<BulletRow icon="close-circle" text="Server URLs or authentication tokens" isDark={isDark} positive={false} />
</View>
@@ -56,7 +66,7 @@ export function TelemetryConsentModal({ visible, onAllow, onDecline }: Props) {
<TouchableOpacity
style={[styles.btn, styles.btnDecline, isDark && styles.btnDeclineDark]}
onPress={onDecline}
accessibilityLabel="No thanks, decline crash reporting"
accessibilityLabel="No thanks, decline crash reporting and analytics"
testID="telemetry-decline-button"
>
<Text style={[styles.btnDeclineText, isDark && styles.btnDeclineTextDark]}>No thanks</Text>
@@ -64,7 +74,7 @@ export function TelemetryConsentModal({ visible, onAllow, onDecline }: Props) {
<TouchableOpacity
style={[styles.btn, styles.btnAllow]}
onPress={onAllow}
accessibilityLabel="Allow anonymous crash reports"
accessibilityLabel="Allow anonymous crash reports and usage analytics"
testID="telemetry-allow-button"
>
<Text style={styles.btnAllowText}>Allow</Text>

View File

@@ -29,8 +29,8 @@
},
"privacy": {
"crashReporting": {
"label": "Crash Reporting",
"description": "Share anonymous crash reports via Sentry to help improve OpenCode. No code or prompts are included."
"label": "Crash Reports & Usage Analytics",
"description": "Share anonymous crash reports (Sentry) and usage analytics (PostHog) to help improve OpenCode. Diagnostic reports you share are also delivered to our support inbox. No code or prompts are included."
},
"privacyPolicy": {
"label": "Privacy Policy",

View File

@@ -29,8 +29,8 @@
},
"privacy": {
"crashReporting": {
"label": "崩溃报告",
"description": "通过 Sentry 分享匿名崩溃报告,帮助改进 OpenCode。报告不包含代码或提示词内容。"
"label": "崩溃报告与使用分析",
"description": "分享匿名崩溃报告(Sentry)和使用分析(PostHog),帮助改进 OpenCode。您分享的诊断报告也会发送至我们的支持收件箱。不包含代码或提示词内容。"
},
"privacyPolicy": {
"label": "隐私政策",