plugins/pm-engineering/skills/feature-flag-guide/SKILL.md
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.
npx skillsauth add mohitagw15856/pm-claude-skills feature-flag-guideInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
Ask for these if not already provided:
Team: [Team name] | Platform: [LaunchDarkly / Split / Unleash / Custom] Document owner: [Name] | Last updated: [Date] Review cycle: Quarterly, and whenever the flag platform changes
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.
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 serviceexp-search-personalized-ranking — experiment on personalized search rankingops-api-rate-limit-override — operational flag to override API rate limitsperm-dashboard-beta-users-only — permission flag gating dashboard for beta usersDo not:
release-JIRA-1234 → not searchable or self-describing)release-dark-mode-jan-2024 → flags outlive their dates)release-new-thing → not useful when you have 50 flags)Complete every item before creating a flag in the production environment.
Before creating the flag:
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()
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
| 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.
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"
Every flag that is not at 0% or 100% rollout requires active monitoring. Do not roll out a flag and walk away.
| 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
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.
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]
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
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]
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.
A flag is stale if ANY of the following are true:
[ ] 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
| 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 |
| 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 |
All flag changes in production must be traceable. Ensure the following are configured in [platform]:
#[team]-flag-changes automatically.development
Analyse competitor moves and translate them into strategic implications for your product roadmap. Use when a competitor announces a new feature, pricing change, partnership, or strategic shift, or when producing a periodic competitive intelligence report. Produces a categorised signal analysis with reactive-vs-proactive assessment, threat ratings, specific roadmap implications, and recommended responses with owners.
development
Build a community management playbook for a brand's social media channels. Use when asked to create guidelines for managing comments, DMs, and community interactions, define a moderation policy, or build response frameworks for social media community managers. Produces a complete playbook with response templates, escalation paths, moderation rules, and tone guidelines.
development
Activate a 4-stage coding discipline framework that forces Claude to plan before coding, isolate changes on a branch, write tests first, and self-review output twice before presenting it. Use when starting a complex coding task, when past Claude sessions produced broken first drafts, or when you want to prevent rework cycles. Produces a confirmed written plan, isolated feature branch, test-first implementation, and a double-reviewed output with a correctness and code-quality checklist.
development
Optimize an article for Answer Engine Optimization (AEO) — restructuring content so AI engines like ChatGPT, Perplexity, and Claude can extract, quote, and cite it. Rewrites headings as questions, drops 50-80 word answer capsules, audits paragraph length, and flags trust signals. Use when asked to AEO-optimize, make content AI-readable, improve AI citation chances, or adapt an article for answer engines.