File size: 10,668 Bytes
93943e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f6895d
 
 
 
 
93943e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f6895d
 
 
 
 
93943e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f6895d
 
 
 
 
93943e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f6895d
 
 
 
 
93943e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f6895d
 
 
 
 
93943e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f6895d
 
 
 
 
93943e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f6895d
 
 
 
 
93943e4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5f6895d
 
 
 
 
93943e4
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
[
  {
    "flag_name": "new_payment_processor",
    "description": "Routes payments through Stripe v3 API instead of legacy v1",
    "rollout_percentage": 0.75,
    "age_days": 90,
    "last_modified_days": 45,
    "owner": "payments-team",
    "owner_active": true,
    "num_code_references": 15,
    "has_dependencies": true,
    "dependent_flags": ["payment_retry_logic_v2"],
    "is_kill_switch": false,
    "has_active_incident": false,
    "usage_last_30d": 95000,
    "in_active_experiment": false,
    "services": ["payment-service", "billing-service"],
    "code_snippet": "processor = StripeV3Client() if flags.get('new_payment_processor') else StripeV1Client()\nresult = processor.charge(amount, currency, token)",
    "last_commit_message": "feat: bump new_payment_processor to 75%",
    "pr_context": "PR #2500: Stripe v3 migration β€” phased rollout. V1 still needed for some enterprise accounts with custom integrations.",
    "related_incidents": ["INC-3200: Stripe v3 timeout spike at 60% rollout (resolved)"],
    "investigation_notes": "Had a timeout issue at 60% rollout (INC-3200) which was fixed. Currently stable at 75%. Enterprise accounts on V1 need migration tooling before going to 100%.",
    "correct_action": "keep",
    "explanation": "Only 75% rolled out with a dependent flag, cross-service β€” not ready for removal"
  },
  {
    "flag_name": "payment_retry_logic_v2",
    "description": "Enables improved retry logic for failed payment transactions",
    "rollout_percentage": 0.75,
    "age_days": 85,
    "last_modified_days": 40,
    "owner": "payments-team",
    "owner_active": true,
    "num_code_references": 7,
    "has_dependencies": false,
    "dependent_flags": [],
    "is_kill_switch": false,
    "has_active_incident": false,
    "usage_last_30d": 30000,
    "in_active_experiment": false,
    "services": ["payment-service"],
    "code_snippet": "retry_strategy = ExponentialBackoffV2() if flags.get('payment_retry_logic_v2') else LinearRetryV1()\nresult = retry_strategy.execute(payment_request)",
    "last_commit_message": "fix: adjust retry backoff multiplier for v2",
    "pr_context": "PR #2520: Retry logic v2 β€” coupled with new_payment_processor migration. Must match parent flag rollout percentage.",
    "related_incidents": [],
    "investigation_notes": "Tightly coupled to new_payment_processor. If parent is at 75%, this must stay at 75%. Rolling one without the other causes payment failures.",
    "correct_action": "keep",
    "explanation": "Depends on new_payment_processor, both at partial rollout β€” keep until parent is fully rolled out"
  },
  {
    "flag_name": "user_profile_redesign",
    "description": "Enables new profile page layout with activity feed",
    "rollout_percentage": 1.0,
    "age_days": 200,
    "last_modified_days": 180,
    "owner": "derek.wong",
    "owner_active": false,
    "num_code_references": 22,
    "has_dependencies": true,
    "dependent_flags": ["profile_activity_feed", "profile_avatar_upload_v2"],
    "is_kill_switch": false,
    "has_active_incident": false,
    "usage_last_30d": 150000,
    "in_active_experiment": false,
    "services": ["user-service", "frontend-web", "media-service"],
    "code_snippet": "const ProfilePage = flags.get('user_profile_redesign')\n  ? React.lazy(() => import('./ProfileV2'))\n  : React.lazy(() => import('./ProfileV1'));",
    "last_commit_message": "feat: profile redesign GA rollout to 100%",
    "pr_context": "PR #1900: Profile redesign by derek.wong (left company). Has child flags for activity feed and avatar upload. No migration plan documented.",
    "related_incidents": [],
    "investigation_notes": "derek.wong left 4 months ago. No handoff document. 2 dependent flags still reference this. Frontend-web team says they 'think it can be removed' but nobody has tested removing it.",
    "correct_action": "deprecate",
    "explanation": "Fully rolled out but has 2 dependent flags and owner left β€” deprecate, notify new owners, schedule cleanup"
  },
  {
    "flag_name": "profile_activity_feed",
    "description": "Shows activity feed section on the new profile page",
    "rollout_percentage": 1.0,
    "age_days": 190,
    "last_modified_days": 170,
    "owner": "derek.wong",
    "owner_active": false,
    "num_code_references": 8,
    "has_dependencies": false,
    "dependent_flags": [],
    "is_kill_switch": false,
    "has_active_incident": false,
    "usage_last_30d": 150000,
    "in_active_experiment": false,
    "services": ["user-service", "frontend-web"],
    "code_snippet": "// Only render if parent flag user_profile_redesign is also enabled\nif (flags.get('profile_activity_feed') && flags.get('user_profile_redesign')) {\n  renderActivityFeed(userId);\n}",
    "last_commit_message": "feat: add activity feed to profile v2",
    "pr_context": "PR #1920: Activity feed β€” child of user_profile_redesign. derek.wong noted: 'remove together with parent flag'",
    "related_incidents": [],
    "investigation_notes": "Code explicitly checks parent flag. Must be cleaned up together with user_profile_redesign. Cannot be independently removed.",
    "correct_action": "deprecate",
    "explanation": "Fully rolled out, inactive owner, depends on parent flag β€” deprecate together with parent"
  },
  {
    "flag_name": "profile_avatar_upload_v2",
    "description": "Enables new avatar upload flow with cropping and filters",
    "rollout_percentage": 0.9,
    "age_days": 120,
    "last_modified_days": 60,
    "owner": "media-team",
    "owner_active": true,
    "num_code_references": 6,
    "has_dependencies": false,
    "dependent_flags": [],
    "is_kill_switch": false,
    "has_active_incident": false,
    "usage_last_30d": 40000,
    "in_active_experiment": false,
    "services": ["media-service", "frontend-web"],
    "code_snippet": "const uploader = flags.get('profile_avatar_upload_v2')\n  ? new CroppingUploader({filters: true})\n  : new BasicUploader();",
    "last_commit_message": "fix: avatar crop ratio on mobile devices",
    "pr_context": "PR #2100: Avatar upload v2 β€” media-team iterating on mobile crop UX. Blocked at 90% due to iOS Safari bug.",
    "related_incidents": ["INC-4100: Avatar upload broken on iOS Safari 17.2 (workaround applied)"],
    "investigation_notes": "Stuck at 90% due to iOS Safari bug (INC-4100). Media-team has a fix in PR #3300 but needs QA. Expected to go to 100% in 2 weeks.",
    "correct_action": "keep",
    "explanation": "90% rollout but not complete, still being iterated on by active team"
  },
  {
    "flag_name": "api_response_compression",
    "description": "Enables gzip compression on API responses over 1KB",
    "rollout_percentage": 1.0,
    "age_days": 300,
    "last_modified_days": 290,
    "owner": "platform-team",
    "owner_active": true,
    "num_code_references": 4,
    "has_dependencies": false,
    "dependent_flags": [],
    "is_kill_switch": false,
    "has_active_incident": false,
    "usage_last_30d": 500000,
    "in_active_experiment": false,
    "services": ["api-gateway", "backend-core"],
    "code_snippet": "app.use(conditionalMiddleware(\n  () => flags.get('api_response_compression'),\n  compression({threshold: 1024})\n));",
    "last_commit_message": "perf: enable response compression globally",
    "pr_context": "PR #1500: API compression β€” reduced bandwidth by 40%. Platform-team confirmed stable for 10 months.",
    "related_incidents": [],
    "investigation_notes": "Running for 10 months without issues. Compression is now the default behavior. Platform-team lead says: 'just remove the flag and hardcode compression on'.",
    "correct_action": "remove",
    "explanation": "Fully rolled out for 10 months across 2 services, no deps, active owner can confirm removal"
  },
  {
    "flag_name": "ml_recommendation_v3",
    "description": "Uses ML model v3 for product recommendations instead of v2",
    "rollout_percentage": 0.5,
    "age_days": 60,
    "last_modified_days": 15,
    "owner": "ml-team",
    "owner_active": true,
    "num_code_references": 10,
    "has_dependencies": true,
    "dependent_flags": ["ml_embedding_cache"],
    "is_kill_switch": false,
    "has_active_incident": false,
    "usage_last_30d": 200000,
    "in_active_experiment": true,
    "services": ["recommendation-service", "ml-inference"],
    "code_snippet": "model = load_model('rec_v3') if flags.get('ml_recommendation_v3') else load_model('rec_v2')\npredictions = model.predict(user_embedding, item_pool)",
    "last_commit_message": "experiment: adjust v3 model serving latency threshold",
    "pr_context": "PR #3100: ML rec v3 A/B test β€” comparing click-through rates. V3 uses new embedding model that requires ml_embedding_cache flag.",
    "related_incidents": [],
    "investigation_notes": "Active A/B test running for 4 weeks. Preliminary results show 8% CTR improvement but 15ms latency increase. ML-team discussing whether to accept the tradeoff.",
    "correct_action": "keep",
    "explanation": "Active A/B experiment at 50%, with dependencies, recently modified"
  },
  {
    "flag_name": "deprecated_analytics_v1",
    "description": "Legacy analytics pipeline that sends events to old warehouse",
    "rollout_percentage": 0.02,
    "age_days": 500,
    "last_modified_days": 400,
    "owner": "data-team",
    "owner_active": true,
    "num_code_references": 30,
    "has_dependencies": false,
    "dependent_flags": [],
    "is_kill_switch": false,
    "has_active_incident": false,
    "usage_last_30d": 100,
    "in_active_experiment": false,
    "services": ["analytics-service", "event-bus", "data-warehouse"],
    "code_snippet": "// WARNING: dual-write to both old and new analytics\nif (flags.get('deprecated_analytics_v1')) {\n  oldWarehouse.ingest(event);  // BigQuery legacy\n}\nnewPipeline.ingest(event);  // Snowflake",
    "last_commit_message": "chore: reduce analytics v1 to 2% for final validation",
    "pr_context": "PR #800: Analytics migration β€” data-team running final validation at 2%. 30 code references across 3 services need coordinated cleanup.",
    "related_incidents": ["INC-2100: Data discrepancy between old and new warehouse (resolved)", "INC-2400: Analytics event loss during migration (resolved)"],
    "investigation_notes": "2 past incidents during migration. Currently at 2% for final validation. Data-team lead says cleanup requires coordinated effort across 3 services and 30 code references. Estimated 2 sprints of work.",
    "correct_action": "escalate",
    "explanation": "Nearly disabled but 30 code references across 3 services, 500 days old β€” needs coordinated cleanup, escalate to data-team lead"
  }
]