Skip to content
Back to skills

Feature Flags Hygiene

ASecurity

Ship code behind flags without accumulating flag rot, through disciplined naming, expiry, and cleanup sweeps. Use when adding a feature flag or auditing the flags already live in a codebase.

  • 7 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 5, 2026
ai-agentsgo

Security analysis

A100/100

Scanned September 5, 2026

npx -y skills add Amey-Thakur/AI-SKILLS --skill feature-flags-hygiene --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Feature Flags Hygiene?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Feature Flags Hygiene
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/amey-thakur-feature-flags-hygiene/badge)](https://www.skillsdirectory.com/skills/amey-thakur-feature-flags-hygiene)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: feature-flags-hygiene
description: Ship code behind flags without accumulating flag rot, through disciplined naming, expiry, and cleanup sweeps. Use when adding a feature flag or auditing the flags already live in a codebase.
---

# Feature flags hygiene

A feature flag lets you ship code dark and turn it on when ready, splitting
deploy from release. The cost arrives later: every live flag doubles the
paths the code can take, and forgotten flags compound until no one knows
which branch runs in production. Treat each flag as debt with a due date.

## Method

1. **Name for intent and lifetime.** Prefix by kind: `release_`, `ops_`,
   `experiment_`, `perm_`. `release_checkout_v2` states its own purpose;
   `flag_new_thing` tells a maintainer nothing. Encode the owning team so an
   orphan has a contact.
2. **Set an expiry at creation.** Every release flag gets a removal date and
   a cleanup ticket in the same pull request that adds it. A flag with no
   death date becomes a permanent branch. Default release flags to 90 days.
3. **Default to off, fail to off.** New flags start disabled. If the flag
   service is unreachable, the code falls back to the old behavior, not to a
   half-shipped one. Test the off path, since it is what most users run.
4. **Keep flag checks shallow.** Read the flag once at the entry point and
   branch there, rather than threading `if flag` through ten functions. Deep
   checks are the ones stranded when you finally delete the flag.
5. **Sweep on a cadence.** Each sprint, list flags past expiry by crossing
   `grep -rn "isEnabled(" src/` against the flag dashboard. For each, remove
   the flag and its dead branch, keeping the winning path.
6. **Delete the flag and the loser together.** Removing a flag means
   deleting the check, the config entry, and the code path that lost. A
   "cleaned up" flag that leaves dead `else` branches is half a job.

## Checks

- Does every live flag have an owner, a purpose legible from its name, and
  an expiry date?
- Are any flags past their removal date still in the codebase?
- If the flag provider errored right now, would the app serve the safe old
  path?

## Boundaries

Kill switches and long-lived operational toggles (`ops_`, `perm_`) are
deliberately permanent: exempt them from expiry sweeps but still name and
document them. Defer to your platform's flag tool (LaunchDarkly, Unleash,
Flagsmith) for storage, targeting, and audit history.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…