Feature Flags Architect
End-to-end discipline for feature flags: classify them, ship them, ramp them, and retire them. Most teams treat flags as throwaway if-statements; this skill treats them as a controlled lifecycle with measurable debt.
When to use
- Adding a new flag and need a rollout plan
- Auditing a codebase for stale or orphaned flags
- Choosing a flag provider (LaunchDarkly vs GrowthBook vs Statsig vs Unleash vs Flipt vs build-your-own)
- Designing a kill-switch path for a risky launch
- Cleaning up flag debt before a release freeze
- Reviewing whether a feature should ship behind a flag at all
Core principle: flags are a lifecycle, not an if
Flags that skip cleanup become debt: dead branches, stale defaults, untested code paths, unbounded blast radius. The three scripts in this skill enforce the lifecycle.
Quick start
The 4 flag types (taxonomy)
Different flag types have different lifespans and ownership. Misclassifying creates debt.
Only Release and Experiment flags should be on a debt-scanner watchlist. Operational and Permission flags are by design long-lived. See references/flag_taxonomy.md for decision tree.
The 3 Python tools
All three are stdlib-only. Run with --help.
flag_debt_scanner.py
Finds flags older than --max-age-days with low usage, suggesting candidates for cleanup.
Detection heuristic:
- Walk
--repofor code references matching common flag-call patterns:flag("..."),isFlagEnabled("..."),featureFlag("..."),getFlag("...")client.variation("...", ...),unleash.isEnabled("..."),growthbook.feature("...")
- For each unique flag identifier, find the oldest commit that introduced it (
git log --diff-filter=A -S <name>). - Flag as DEBT if introduced >
--max-age-daysago AND used in ≤--min-usesplaces.
Outputs flag name, age in days, file references, suggested action. JSON mode is CI-friendly.
rollout_planner.py
Generates a phased rollout schedule from population size, target percent, duration, and strategy.
Strategies:
ring: 1% → 5% → 25% → 50% → 100%, evenly spaced. Default for risky launches.linear: constant rate per day. Default for medium-risk.log: rapid early, slow tail. Default for low-risk launches with confidence.cohort: by named cohort (internal → beta → free → paid → all).
Outputs a markdown table with date, percent, expected user count, abort criteria, and verification step per phase.
kill_switch_audit.py
Cross-references code-discovered flags against documentation to verify each has a kill switch path written down.
What it checks:
- Every code-discovered flag has an entry in
--flag-doc - Each entry declares: owner, type, kill-switch trigger, monitoring dashboard
- Reports flags missing documentation (FAIL) or missing fields (WARN)
Use as a pre-merge gate before any new flag ships.
Provider chooser (5 + DIY)
Decision rules:
- <50 flags + no targeting → DIY with config file or env vars
- Need analytics + experimentation → Statsig or GrowthBook
- Compliance/SOC2 audit logs required → LaunchDarkly
- Self-hosting required (data residency / air-gapped) → Unleash or Flipt
- See
references/provider_comparison.mdfor detail.
Workflows
Workflow 1: Ship a new feature behind a flag
Workflow 2: Quarterly flag cleanup
Workflow 3: Choose a provider
Workflow 4: Design a kill switch
References
references/flag_taxonomy.md— 4 types, decision tree, ownership, lifespanreferences/provider_comparison.md— LaunchDarkly / GrowthBook / Statsig / Unleash / Flipt / DIY trade-offsreferences/rollout_strategies.md— ring / linear / log / cohort / geo, abort criteria, monitoringreferences/flag_lifecycle.md— request → design → ship → ramp → cleanup → archive
Slash command
/flag-cleanup — Run the full cleanup workflow on the current repo: scan for debt, generate a removal plan, audit kill switches.
Asset templates
assets/flag_request_template.md— fill-in form for new flag requests (name, owner, type, kill switch, rollout plan)
Anti-patterns
- Permanent flag with
if (FLAG_FOO)50 places — should be a Permission flag with a runtime config, not a Release flag - Flag with no owner — when the original engineer leaves, no one cleans it up
- No kill switch documented — when the feature breaks, no one knows how to disable it
- A/B test that ran 6 months — pick a winner; running indefinitely is debt
- Flags as feature toggles for cosmetic changes — ship via deploy, not flag
Verifiable success
A team using this skill should achieve:
- 100% of new flags pass
kill_switch_audit.pyat merge time flag_debt_scanner.py --max-age-days 90returns ≤5 stale flags repo-wide- Every flag has a documented owner, type, and kill switch
- Mean time to retire a Release flag: <60 days from 100% rollout


