Feature Flag Guide Skill

Write a feature flag management guide and lifecycle playbook for a service or team — covering flag taxonomy, creation checklist, rollout strategy, monitoring requirements, cleanup policy, and governance.

Feature Flag Guide Skill — The Skill Playground: pick the Executive Update skill, fill in a few notes, hit run, and watch a structured executive… (from the mohitagw15856/pm-claude-skills README)

From the mohitagw15856/pm-claude-skills README — shows the whole collection, not only this skill. · view on GitHub

How to use it

Claude Code
  1. Run the line below. It pulls the whole folder into ~/.claude/skills/feature-flag-guide.
  2. Describe your job in plain words. Claude Code follows the skill from there.
Claude Code — installs the whole folder, not just SKILL.md
npx degit mohitagw15856/pm-claude-skills/skills/feature-flag-guide#main ~/.claude/skills/feature-flag-guide

For one project only, change the path to .claude/skills/feature-flag-guide.

Claude (web or desktop app)
  1. On this page open ⋯ → Download .md.
  2. Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
  3. Pick the file and Save. Claude shows the name and description and runs a security scan.
  4. Check the skill is switched on.
  5. Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
  1. ChatGPT: make a Project and paste it into Instructions.
  2. Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
  • Check which app you pasted it into — the steps above name the right one.
  • Some skills need the paid tier of Claude or ChatGPT.
Step-by-step guide with screenshots · Ask in the forum

Paste into Claude, ChatGPT or Cursor.

Source of Feature Flag Guide Skill

Show the full text378 lines
namedescription
feature-flag-guideWrite a feature flag management guide and lifecycle playbook for a service or team — covering flag taxonomy, creation checklist, rollout strategy, monitoring requirements, cleanup policy, and governance. Use when asked to document feature flag practices, create a flag rollout plan, write a feature flag policy, or guide a team on flag lifecycle management. Produces a flag lifecycle playbook, taxonomy reference, per-flag creation template, rollout decision tree, and cleanup checklist.

Feature Flag Guide Skill

Produce a complete feature flag management guide for a service or team — covering how flags are named and categorised, how to create and roll out a flag safely, what to monitor during rollout, when and how to clean up flags, and who is responsible for each stage. Feature flags without discipline become permanent technical debt. This guide gives the team a repeatable process so flags are created intentionally, rolled out safely, and removed when done.

Required Inputs

Ask for these if not already provided:

  • Service or team name — scope of the guide
  • Feature flag platform — LaunchDarkly, Split, Unleash, Flagsmith, Flipt, or a custom/in-house solution
  • Flag being documented (if writing a per-flag guide) or "general guide" (if writing team-wide policy)
  • Rollout constraints — any compliance, data privacy, or contractual constraints on who can see a feature (e.g. HIPAA, EU-only, enterprise customers only)

Output Format


Feature Flag Management Guide: [Service / Team Name]

Team: [Team name] | Platform: [LaunchDarkly / Split / Unleash / Custom] Document owner: [Name] | Last updated: [Date] Review cycle: Quarterly, and whenever the flag platform changes


1. Flag Taxonomy

Every flag belongs to exactly one category. The category determines default behaviour, who can enable it in production, and when it must be cleaned up.

Type Purpose Default state Production gate Max lifetime
Release flag Controls rollout of a new feature — decouples deploy from release Off Tech lead approval 90 days from feature launch
Experiment flag A/B or multivariate test — measures impact of a change Off (control group) Product + tech lead Duration of experiment + 30 days
Ops flag Operational control — circuit breaker, kill switch, throttle On (normal behaviour) On-call engineer can toggle Indefinite (review annually)
Permission flag Gates access by user segment, tier, or region Off (restricted) Product + Account owner Indefinite (review annually)

When in doubt: If the flag is temporary (tied to a specific feature launch), it is a Release flag. If it will exist forever as a control knob, it is an Ops flag.


2. Flag Naming Convention

All flags must follow this naming scheme:

[type]-[service]-[feature-description]
Segment Values Example
type release, exp, ops, perm release
service Short service identifier, lowercase, hyphenated payments
feature-description Kebab-case description, max 5 words new-checkout-flow

Full examples:

  • release-payments-new-checkout-flow — release flag for a new checkout feature in the payments service
  • exp-search-personalized-ranking — experiment on personalized search ranking
  • ops-api-rate-limit-override — operational flag to override API rate limits
  • perm-dashboard-beta-users-only — permission flag gating dashboard for beta users

Do not:

  • Use ticket numbers in flag names (release-JIRA-1234 → not searchable or self-describing)
  • Use dates in flag names (release-dark-mode-jan-2024 → flags outlive their dates)
  • Use vague names (release-new-thing → not useful when you have 50 flags)

3. Flag Creation Checklist

Complete every item before creating a flag in the production environment.

Before creating the flag:

  • Flag type determined from taxonomy (Section 1)
  • Flag name follows naming convention (Section 2)
  • Flag owner assigned — one named engineer responsible for cleanup
  • Cleanup date set in the flag description field (for Release and Experiment flags)
  • Rollout strategy defined — see Section 4
  • Monitoring plan defined — see Section 5
  • Code review approved with flag guard in place

Flag description field (required):

Type: [Release / Experiment / Ops / Permission]
Owner: [Name]
Linked ticket: [JIRA-XXXX or GitHub issue URL]
Purpose: [One sentence — what this flag controls]
Cleanup by: [Date — required for Release and Experiment flags; "Annual review" for Ops/Permission]
Rollout plan: [Link to this document or inline summary]

Code requirements:

# Good — behaviour is clear when flag is off, and cleanup is obvious
if flag_client.is_enabled("release-[service]-[feature]", user_context):
    return new_feature_handler(request)
else:
    return existing_handler(request)

# Bad — nested flags, ternaries, and implicit defaults make cleanup error-prone
result = new_handler() if (f1 and not f2) or f3 else old_handler()

4. Rollout Strategy

Decision Tree

Use this decision tree to pick the right rollout strategy for a Release or Experiment flag:

Is the change reversible without a deploy?
├── No → Use an Ops flag with manual enable, not a percentage rollout
└── Yes → Continue

Is there a user-level identifier available (user ID, session ID)?
├── No → Use server-side percentage (stateless, but inconsistent per user)
└── Yes → Use user-based percentage (consistent experience per user) ← preferred

Is the change risky (touches payments, auth, or data writes)?
├── Yes → Start at 1% → 5% → 25% → 50% → 100%, with 24-hour holds
└── No → Start at 10% → 50% → 100%, with 4-hour holds

Does the change affect specific customer tiers or geographies?
├── Yes → Use segment-based targeting, not percentage rollout
└── No → Use percentage rollout
Rollout Stages
Stage Percentage Hold duration Pass criteria before advancing
Canary 1% 24 hours Error rate within SLO, no P1 incidents
Early rollout 5–10% 24 hours Error rate and latency match control group
Partial rollout 25–50% 24–48 hours Business metrics not degraded vs. control
Majority 75% 24 hours Final check — no regressions
Full rollout 100% 48 hours Stable — schedule cleanup

Do not skip stages for Release flags on production. Speed of rollout is not worth a production incident.

Segment-Based Targeting

Use segment targeting when the rollout must be restricted:

# LaunchDarkly segment example — adapt for your platform
targeting_rules:
  - clause:
      attribute: "subscription_tier"
      operator: "in"
      values: ["enterprise", "team"]
    serve: "on"
  - clause:
      attribute: "country"
      operator: "in"
      values: ["US", "CA", "GB"]
    serve: "on"
  default: "off"

5. Monitoring Requirements

Every flag that is not at 0% or 100% rollout requires active monitoring. Do not roll out a flag and walk away.

Required Metrics Per Flag
Metric What to compare Alert threshold
Error rate Flag-on cohort vs. flag-off cohort >2× baseline error rate in flag-on group
p99 latency Flag-on vs. flag-off >20% higher latency in flag-on group
[Primary business metric] Flag-on vs. flag-off >5% degradation in flag-on group
[Conversion / completion rate] Flag-on vs. flag-off >2% drop in flag-on group

Setting up split metric monitoring in [LaunchDarkly / Split / Datadog]:

1. Navigate to the flag → Metrics tab
2. Add metric: [primary business metric]
3. Add metric: error_rate (service-level)
4. Add metric: p99_latency (endpoint-level)
5. Set alert: notify [flag owner] in Slack #[team-channel] if metric degrades by [threshold]
6. Set experiment duration: [N days] if this is an Experiment flag
Guardrail Metrics

These metrics must never degrade, regardless of what the primary metric shows. If a guardrail is breached, roll back immediately — do not wait for investigation.

  • Error rate exceeds SLO threshold ([X]%)
  • p99 latency exceeds SLO threshold ([Y] ms)
  • [Service-specific guardrail — e.g. payment failure rate, auth failure rate]

Immediate rollback command if guardrail is breached:

# [LaunchDarkly CLI]
ld-cli flag update [project-key] [flag-key] --default-variation off

# [Split CLI]
split-cli update-treatment [flag-name] --treatment "off" --percentage 100

# [Unleash CLI / API]
curl -X POST https://[unleash-host]/api/admin/features/[flag-name]/disable \
  -H "Authorization: [admin-token]"

# [Custom — adapt to your implementation]
[command or dashboard step]

6. Per-Flag Creation Template

Copy this template into your flag's description field and the linked ticket when creating a new flag:

## Flag: [flag-name]

**Type:** [Release / Experiment / Ops / Permission]
**Owner:** [Name] ([Slack handle])
**Created:** [Date]
**Cleanup by:** [Date]
**Linked ticket:** [URL]

### Purpose
[One paragraph: what this flag controls, why it exists, what "on" and "off" mean]

### Rollout Plan
| Stage | Target | Date | Approved by |
|---|---|---|---|
| Canary | 1% | [Date] | [Name] |
| Early | 10% | [Date] | [Name] |
| Partial | 50% | [Date] | [Name] |
| Full | 100% | [Date] | [Name] |

### Monitoring
- Primary metric: [metric name and dashboard link]
- Guardrail metrics: error rate < [X]%, p99 < [Y] ms
- Alert channel: #[team-channel]

### Rollback Procedure
[Exact steps to turn the flag off in an emergency — should take < 2 minutes]

### Cleanup Checklist
- [ ] Flag at 100% for 48+ hours with no incidents
- [ ] Code path for flag-off branch removed from codebase
- [ ] Flag deleted from [platform]
- [ ] Ticket closed

7. Emergency Kill-Switch Procedure

When a flag needs to be disabled immediately due to a production incident:

Time target: flag disabled within 2 minutes of decision.

1. Go to [platform URL] — bookmark this: [URL]
2. Search for the flag by name: [flag-name]
3. Set to 0% / "off" for ALL users
4. Verify the service error rate drops within 60 seconds
5. Post to #incidents:
   "🟡 Feature flag [flag-name] disabled — rolling back [feature description].
    Owner: [name]. Error rate before: [X]%. Monitoring for recovery."
6. Page the flag owner if not already aware

For ops flags (kill switches that must turn OFF normally-on behaviour):

# These flags are "on" by default and turned "off" to disable a feature
# Confirm the flag polarity before toggling — "off" may mean "disabled" or "enabled" depending on naming
# Flag [flag-name]: OFF = [feature behaviour when off]
[kill switch command for your platform]

8. Stale Flag Policy and Cleanup

Stale flags are flags that are at 100% rollout, have been at 100% for >48 hours, or are past their cleanup date. Stale flags are technical debt.

Stale Flag Definition

A flag is stale if ANY of the following are true:

  • It is a Release flag past its cleanup date
  • It has been at 100% (or 0%) rollout for more than 30 days
  • Its linked ticket is closed and code cleanup has not happened
  • Its owner has left the team
Cleanup Checklist
[ ] Flag is at 100% rollout and has been stable for 48+ hours
[ ] Monitoring shows no issues for the flag-on cohort
[ ] Code changes:
    [ ] Remove the flag check from application code
    [ ] Remove the "off" code path entirely — do not leave dead code
    [ ] Remove any flag-related tests that test the off behaviour
    [ ] Update any documentation that references the flag
[ ] PR merged and deployed to production
[ ] Flag deleted from [platform] (do not just disable — delete)
[ ] Cleanup ticket closed
[ ] Flag owner confirms cleanup in Slack: "Flag [name] has been cleaned up — [commit link]"

Automated stale flag detection:

# Run weekly — flags past cleanup date or at 100% for > 30 days
# [Platform-specific query — adapt:]

# LaunchDarkly API
curl -s "https://app.launchdarkly.com/api/v2/flags/[project-key]" \
  -H "Authorization: [api-key]" | \
  jq '.items[] | select(.creationDate < (now - 2592000) * 1000) | {key: .key, created: .creationDate}'

# Notify #engineering-housekeeping with list of stale flags
Stale Flag Escalation
Age past cleanup date Action
0–14 days Slack reminder to flag owner
14–30 days Slack reminder to flag owner + tech lead
30+ days Tech lead assigns cleanup, creates ticket with P2 priority
60+ days Engineering manager reviews — flag may be force-deleted

9. Governance

Who Can Do What
Action Who Approval required
Create a flag (any environment) Any engineer None — but must complete creation checklist
Enable a flag in development Any engineer None
Enable a flag in staging Any engineer None
Enable a flag in production (0–10%) Flag owner Tech lead awareness
Advance rollout in production (10–100%) Flag owner Tech lead sign-off per stage
Enable an Ops flag in production On-call engineer None — these are break-glass controls
Delete a flag Flag owner Tech lead confirmation that code cleanup is done
Create a Permission flag Flag owner Product manager approval
Audit Logging

All flag changes in production must be traceable. Ensure the following are configured in [platform]:

  • Change log: Every production flag change logs: who changed it, what they changed, and when.
  • Slack notifications: Production flag changes post to #[team]-flag-changes automatically.
  • Quarterly review: Every quarter, the tech lead reviews the full flag inventory, confirms owners are current, and removes flags with no owner.

Quality Checks

  • Every flag has an owner named in its description — no orphan flags
  • Release and Experiment flags have a cleanup date set — not open-ended
  • Monitoring is configured for every flag currently between 1–99% rollout
  • The emergency kill-switch procedure has been tested — on-call engineers have bookmarked the platform URL and know the steps
  • Stale flag detection runs automatically and results are reviewed weekly
  • Code review checklist includes: "Does this PR introduce a flag? If yes, is the creation checklist complete?"
  • At least one person other than the flag owner knows how to disable any given flag in an emergency

Anti-Patterns

  • Do not create release flags without a cleanup date — flags without expiry dates become permanent technical debt that accumulates silently until the codebase is unmaintainable
  • Do not skip monitoring setup for flags between 1–99% rollout — a partially-rolled-out flag without metric comparison is a risk without a sensor
  • Do not nest flags inside other flags — compound flag logic makes cleanup nearly impossible and creates untestable code paths
  • Do not allow flag owners to leave the team without reassigning ownership — orphan flags with no owner never get cleaned up
  • Do not use feature flags as a permanent configuration system — flags that have been at 100% or 0% for more than 30 days must be cleaned up; using flags as permanent config couples business logic to a feature flag platform
1---
2name: feature-flag-guide
3description: "Write a feature flag management guide and lifecycle playbook for a service or team — covering flag taxonomy, creation checklist, rollout strategy, monitoring requirements, cleanup policy, and governance. Use when asked to document feature flag practices, create a flag rollout plan, write a feature flag policy, or guide a team on flag lifecycle management. Produces a flag lifecycle playbook, taxonomy reference, per-flag creation template, rollout decision tree, and cleanup checklist."
4---
5 
6# Feature Flag Guide Skill
7 
8Produce a complete feature flag management guide for a service or team — covering how flags are named and categorised, how to create and roll out a flag safely, what to monitor during rollout, when and how to clean up flags, and who is responsible for each stage. Feature flags without discipline become permanent technical debt. This guide gives the team a repeatable process so flags are created intentionally, rolled out safely, and removed when done.
9 
10## Required Inputs
11 
12Ask for these if not already provided:
13- **Service or team name** — scope of the guide
14- **Feature flag platform** — LaunchDarkly, Split, Unleash, Flagsmith, Flipt, or a custom/in-house solution
15- **Flag being documented** (if writing a per-flag guide) or "general guide" (if writing team-wide policy)
16- **Rollout constraints** — any compliance, data privacy, or contractual constraints on who can see a feature (e.g. HIPAA, EU-only, enterprise customers only)
17 
18## Output Format
19 
20---
21 
22# Feature Flag Management Guide: [Service / Team Name]
23 
24**Team:** [Team name] | **Platform:** [LaunchDarkly / Split / Unleash / Custom]
25**Document owner:** [Name] | **Last updated:** [Date]
26**Review cycle:** Quarterly, and whenever the flag platform changes
27 
28---
29 
30## 1. Flag Taxonomy
31 
32Every flag belongs to exactly one category. The category determines default behaviour, who can enable it in production, and when it must be cleaned up.
33 
34| Type | Purpose | Default state | Production gate | Max lifetime |
35|---|---|---|---|---|
36| **Release flag** | Controls rollout of a new feature — decouples deploy from release | Off | Tech lead approval | 90 days from feature launch |
37| **Experiment flag** | A/B or multivariate test — measures impact of a change | Off (control group) | Product + tech lead | Duration of experiment + 30 days |
38| **Ops flag** | Operational control — circuit breaker, kill switch, throttle | On (normal behaviour) | On-call engineer can toggle | Indefinite (review annually) |
39| **Permission flag** | Gates access by user segment, tier, or region | Off (restricted) | Product + Account owner | Indefinite (review annually) |
40 
41**When in doubt:** If the flag is temporary (tied to a specific feature launch), it is a Release flag. If it will exist forever as a control knob, it is an Ops flag.
42 
43---
44 
45## 2. Flag Naming Convention
46 
47All flags must follow this naming scheme:
48 
49```
50[type]-[service]-[feature-description]
51```
52 
53| Segment | Values | Example |
54|---|---|---|
55| type | `release`, `exp`, `ops`, `perm` | `release` |
56| service | Short service identifier, lowercase, hyphenated | `payments` |
57| feature-description | Kebab-case description, max 5 words | `new-checkout-flow` |
58 
59**Full examples:**
60- `release-payments-new-checkout-flow` — release flag for a new checkout feature in the payments service
61- `exp-search-personalized-ranking` — experiment on personalized search ranking
62- `ops-api-rate-limit-override` — operational flag to override API rate limits
63- `perm-dashboard-beta-users-only` — permission flag gating dashboard for beta users
64 
65**Do not:**
66- Use ticket numbers in flag names (`release-JIRA-1234` → not searchable or self-describing)
67- Use dates in flag names (`release-dark-mode-jan-2024` → flags outlive their dates)
68- Use vague names (`release-new-thing` → not useful when you have 50 flags)
69 
70---
71 
72## 3. Flag Creation Checklist
73 
74Complete every item before creating a flag in the production environment.
75 
76**Before creating the flag:**
77- [ ] Flag type determined from taxonomy (Section 1)
78- [ ] Flag name follows naming convention (Section 2)
79- [ ] Flag owner assigned — one named engineer responsible for cleanup
80- [ ] Cleanup date set in the flag description field (for Release and Experiment flags)
81- [ ] Rollout strategy defined — see Section 4
82- [ ] Monitoring plan defined — see Section 5
83- [ ] Code review approved with flag guard in place
84 
85**Flag description field (required):**
86```
87Type: [Release / Experiment / Ops / Permission]
88Owner: [Name]
89Linked ticket: [JIRA-XXXX or GitHub issue URL]
90Purpose: [One sentence — what this flag controls]
91Cleanup by: [Date — required for Release and Experiment flags; "Annual review" for Ops/Permission]
92Rollout plan: [Link to this document or inline summary]
93```
94 
95**Code requirements:**
96```python
97# Good — behaviour is clear when flag is off, and cleanup is obvious
98if flag_client.is_enabled("release-[service]-[feature]", user_context):
99 return new_feature_handler(request)
100else:
101 return existing_handler(request)
102 
103# Bad — nested flags, ternaries, and implicit defaults make cleanup error-prone
104result = new_handler() if (f1 and not f2) or f3 else old_handler()
105```
106 
107---
108 
109## 4. Rollout Strategy
110 
111### Decision Tree
112 
113Use this decision tree to pick the right rollout strategy for a Release or Experiment flag:
114 
115```
116Is the change reversible without a deploy?
117├── No → Use an Ops flag with manual enable, not a percentage rollout
118└── Yes → Continue
119 
120Is there a user-level identifier available (user ID, session ID)?
121├── No → Use server-side percentage (stateless, but inconsistent per user)
122└── Yes → Use user-based percentage (consistent experience per user) ← preferred
123 
124Is the change risky (touches payments, auth, or data writes)?
125├── Yes → Start at 1% → 5% → 25% → 50% → 100%, with 24-hour holds
126└── No → Start at 10% → 50% → 100%, with 4-hour holds
127 
128Does the change affect specific customer tiers or geographies?
129├── Yes → Use segment-based targeting, not percentage rollout
130└── No → Use percentage rollout
131```
132 
133### Rollout Stages
134 
135| Stage | Percentage | Hold duration | Pass criteria before advancing |
136|---|---|---|---|
137| Canary | 1% | 24 hours | Error rate within SLO, no P1 incidents |
138| Early rollout | 5–10% | 24 hours | Error rate and latency match control group |
139| Partial rollout | 25–50% | 24–48 hours | Business metrics not degraded vs. control |
140| Majority | 75% | 24 hours | Final check — no regressions |
141| Full rollout | 100% | 48 hours | Stable — schedule cleanup |
142 
143**Do not skip stages for Release flags on production.** Speed of rollout is not worth a production incident.
144 
145### Segment-Based Targeting
146 
147Use segment targeting when the rollout must be restricted:
148 
149```yaml
150# LaunchDarkly segment example — adapt for your platform
151targeting_rules:
152 - clause:
153 attribute: "subscription_tier"
154 operator: "in"
155 values: ["enterprise", "team"]
156 serve: "on"
157 - clause:
158 attribute: "country"
159 operator: "in"
160 values: ["US", "CA", "GB"]
161 serve: "on"
162 default: "off"
163```
164 
165---
166 
167## 5. Monitoring Requirements
168 
169Every flag that is not at 0% or 100% rollout requires active monitoring. Do not roll out a flag and walk away.
170 
171### Required Metrics Per Flag
172 
173| Metric | What to compare | Alert threshold |
174|---|---|---|
175| Error rate | Flag-on cohort vs. flag-off cohort | >2× baseline error rate in flag-on group |
176| p99 latency | Flag-on vs. flag-off | >20% higher latency in flag-on group |
177| [Primary business metric] | Flag-on vs. flag-off | >5% degradation in flag-on group |
178| [Conversion / completion rate] | Flag-on vs. flag-off | >2% drop in flag-on group |
179 
180**Setting up split metric monitoring in [LaunchDarkly / Split / Datadog]:**
181```
1821. Navigate to the flag → Metrics tab
1832. Add metric: [primary business metric]
1843. Add metric: error_rate (service-level)
1854. Add metric: p99_latency (endpoint-level)
1865. Set alert: notify [flag owner] in Slack #[team-channel] if metric degrades by [threshold]
1876. Set experiment duration: [N days] if this is an Experiment flag
188```
189 
190### Guardrail Metrics
191 
192These metrics must never degrade, regardless of what the primary metric shows. If a guardrail is breached, roll back immediately — do not wait for investigation.
193 
194- Error rate exceeds SLO threshold ([X]%)
195- p99 latency exceeds SLO threshold ([Y] ms)
196- [Service-specific guardrail — e.g. payment failure rate, auth failure rate]
197 
198**Immediate rollback command if guardrail is breached:**
199```bash
200# [LaunchDarkly CLI]
201ld-cli flag update [project-key] [flag-key] --default-variation off
202 
203# [Split CLI]
204split-cli update-treatment [flag-name] --treatment "off" --percentage 100
205 
206# [Unleash CLI / API]
207curl -X POST https://[unleash-host]/api/admin/features/[flag-name]/disable \
208 -H "Authorization: [admin-token]"
209 
210# [Custom — adapt to your implementation]
211[command or dashboard step]
212```
213 
214---
215 
216## 6. Per-Flag Creation Template
217 
218Copy this template into your flag's description field and the linked ticket when creating a new flag:
219 
220```markdown
221## Flag: [flag-name]
222 
223**Type:** [Release / Experiment / Ops / Permission]
224**Owner:** [Name] ([Slack handle])
225**Created:** [Date]
226**Cleanup by:** [Date]
227**Linked ticket:** [URL]
228 
229### Purpose
230[One paragraph: what this flag controls, why it exists, what "on" and "off" mean]
231 
232### Rollout Plan
233| Stage | Target | Date | Approved by |
234|---|---|---|---|
235| Canary | 1% | [Date] | [Name] |
236| Early | 10% | [Date] | [Name] |
237| Partial | 50% | [Date] | [Name] |
238| Full | 100% | [Date] | [Name] |
239 
240### Monitoring
241- Primary metric: [metric name and dashboard link]
242- Guardrail metrics: error rate < [X]%, p99 < [Y] ms
243- Alert channel: #[team-channel]
244 
245### Rollback Procedure
246[Exact steps to turn the flag off in an emergency — should take < 2 minutes]
247 
248### Cleanup Checklist
249- [ ] Flag at 100% for 48+ hours with no incidents
250- [ ] Code path for flag-off branch removed from codebase
251- [ ] Flag deleted from [platform]
252- [ ] Ticket closed
253```
254 
255---
256 
257## 7. Emergency Kill-Switch Procedure
258 
259When a flag needs to be disabled immediately due to a production incident:
260 
261**Time target: flag disabled within 2 minutes of decision.**
262 
263```
2641. Go to [platform URL] — bookmark this: [URL]
2652. Search for the flag by name: [flag-name]
2663. Set to 0% / "off" for ALL users
2674. Verify the service error rate drops within 60 seconds
2685. Post to #incidents:
269 "🟡 Feature flag [flag-name] disabled — rolling back [feature description].
270 Owner: [name]. Error rate before: [X]%. Monitoring for recovery."
2716. Page the flag owner if not already aware
272```
273 
274**For ops flags (kill switches that must turn OFF normally-on behaviour):**
275```bash
276# These flags are "on" by default and turned "off" to disable a feature
277# Confirm the flag polarity before toggling — "off" may mean "disabled" or "enabled" depending on naming
278# Flag [flag-name]: OFF = [feature behaviour when off]
279[kill switch command for your platform]
280```
281 
282---
283 
284## 8. Stale Flag Policy and Cleanup
285 
286Stale flags are flags that are at 100% rollout, have been at 100% for >48 hours, or are past their cleanup date. Stale flags are technical debt.
287 
288### Stale Flag Definition
289 
290A flag is stale if ANY of the following are true:
291- It is a Release flag past its cleanup date
292- It has been at 100% (or 0%) rollout for more than 30 days
293- Its linked ticket is closed and code cleanup has not happened
294- Its owner has left the team
295 
296### Cleanup Checklist
297 
298```
299[ ] Flag is at 100% rollout and has been stable for 48+ hours
300[ ] Monitoring shows no issues for the flag-on cohort
301[ ] Code changes:
302 [ ] Remove the flag check from application code
303 [ ] Remove the "off" code path entirely — do not leave dead code
304 [ ] Remove any flag-related tests that test the off behaviour
305 [ ] Update any documentation that references the flag
306[ ] PR merged and deployed to production
307[ ] Flag deleted from [platform] (do not just disable — delete)
308[ ] Cleanup ticket closed
309[ ] Flag owner confirms cleanup in Slack: "Flag [name] has been cleaned up — [commit link]"
310```
311 
312**Automated stale flag detection:**
313```bash
314# Run weekly — flags past cleanup date or at 100% for > 30 days
315# [Platform-specific query — adapt:]
316 
317# LaunchDarkly API
318curl -s "https://app.launchdarkly.com/api/v2/flags/[project-key]" \
319 -H "Authorization: [api-key]" | \
320 jq '.items[] | select(.creationDate < (now - 2592000) * 1000) | {key: .key, created: .creationDate}'
321 
322# Notify #engineering-housekeeping with list of stale flags
323```
324 
325### Stale Flag Escalation
326 
327| Age past cleanup date | Action |
328|---|---|
329| 0–14 days | Slack reminder to flag owner |
330| 14–30 days | Slack reminder to flag owner + tech lead |
331| 30+ days | Tech lead assigns cleanup, creates ticket with P2 priority |
332| 60+ days | Engineering manager reviews — flag may be force-deleted |
333 
334---
335 
336## 9. Governance
337 
338### Who Can Do What
339 
340| Action | Who | Approval required |
341|---|---|---|
342| Create a flag (any environment) | Any engineer | None — but must complete creation checklist |
343| Enable a flag in development | Any engineer | None |
344| Enable a flag in staging | Any engineer | None |
345| Enable a flag in production (0–10%) | Flag owner | Tech lead awareness |
346| Advance rollout in production (10–100%) | Flag owner | Tech lead sign-off per stage |
347| Enable an Ops flag in production | On-call engineer | None — these are break-glass controls |
348| Delete a flag | Flag owner | Tech lead confirmation that code cleanup is done |
349| Create a Permission flag | Flag owner | Product manager approval |
350 
351### Audit Logging
352 
353All flag changes in production must be traceable. Ensure the following are configured in [platform]:
354 
355- **Change log:** Every production flag change logs: who changed it, what they changed, and when.
356- **Slack notifications:** Production flag changes post to `#[team]-flag-changes` automatically.
357- **Quarterly review:** Every quarter, the tech lead reviews the full flag inventory, confirms owners are current, and removes flags with no owner.
358 
359---
360 
361## Quality Checks
362 
363- [ ] Every flag has an owner named in its description — no orphan flags
364- [ ] Release and Experiment flags have a cleanup date set — not open-ended
365- [ ] Monitoring is configured for every flag currently between 1–99% rollout
366- [ ] The emergency kill-switch procedure has been tested — on-call engineers have bookmarked the platform URL and know the steps
367- [ ] Stale flag detection runs automatically and results are reviewed weekly
368- [ ] Code review checklist includes: "Does this PR introduce a flag? If yes, is the creation checklist complete?"
369- [ ] At least one person other than the flag owner knows how to disable any given flag in an emergency
370 
371## Anti-Patterns
372 
373- [ ] Do not create release flags without a cleanup date — flags without expiry dates become permanent technical debt that accumulates silently until the codebase is unmaintainable
374- [ ] Do not skip monitoring setup for flags between 1–99% rollout — a partially-rolled-out flag without metric comparison is a risk without a sensor
375- [ ] Do not nest flags inside other flags — compound flag logic makes cleanup nearly impossible and creates untestable code paths
376- [ ] Do not allow flag owners to leave the team without reassigning ownership — orphan flags with no owner never get cleaned up
377- [ ] Do not use feature flags as a permanent configuration system — flags that have been at 100% or 0% for more than 30 days must be cleaned up; using flags as permanent config couples business logic to a feature flag platform
378 

Discussion

Alternatives

Also in Specs & PRDsSee all 277 in Product →