Skip to content
Back to skills

Add Feature Flag

ASecurity

Use when a ticket asks to ship behaviour behind a toggle — a gradual rollout, a kill switch, an A/B variant, a dark launch — or to add, wire, or clean up a feature flag with a default, an owner, and a removal plan. Invoke for "put it behind a flag", "add a kill switch", "roll out to 10%", or "remove the flag now that it's fully on".

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 28, 2026
ai-agentspythonrustgojavarubykotlinreactnodetestingsecurity

Works with

  • mcp

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add tmj-90/gaffer --skill add-feature-flag --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Add Feature Flag?

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

Security grade badge for Add Feature Flag
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tmj-90-add-feature-flag/badge)](https://www.skillsdirectory.com/skills/tmj-90-add-feature-flag)

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: add-feature-flag
description: Use when a ticket asks to ship behaviour behind a toggle — a gradual rollout, a kill switch, an A/B variant, a dark launch — or to add, wire, or clean up a feature flag with a default, an owner, and a removal plan. Invoke for "put it behind a flag", "add a kill switch", "roll out to 10%", or "remove the flag now that it's fully on".
stack: [node, python, go, java, rust, csharp, kotlin, ruby, react, web]
area: workflow
---

# Add a feature flag

A flag decouples deploy from release: code ships dark, is switched on deliberately, and
can be switched off in seconds. Every flag is also a branch in the code that someone must
test and later delete. Add it so both paths are correct, the default is safe, and its
removal is already planned.

## Steps

1. **Classify the flag** (Pete Hodgson, "Feature Toggles"); the category sets its
   lifetime and how dynamic it must be:
   - **release** — hides unfinished or unreleased work; lives days to weeks; usually a
     static per-deploy value. The common case.
   - **ops / kill switch** — lets operators turn off a costly or risky path under load;
     may live long; must be changeable at runtime without a deploy.
   - **experiment** — A/B cohorts; decided per request/user; needs consistent bucketing.
   - **permission** — per-user or per-plan access; long-lived; this is product logic, so
     treat it as an entitlement, not a temporary flag.
2. **Use the repo's flag mechanism.** A flags-service SDK, a config-driven module, env
   vars, a settings table. Call `search_lore` for naming and where flags are declared. If
   there is none, propose the smallest one (a typed config module with defaults, see the
   `add-config-option` skill) via `request_decision` before building infrastructure.
3. **Name, type and default it.** A descriptive, namespaced name
   (`checkout.new-address-form`), boolean unless variants are required. Never reuse a
   retired flag's name: old code still reading it will wake up. The default is the SAFE
   state — the current behaviour — and it is also what the code does when the flag
   source is unreachable or the value is malformed.
4. **Declare once; decide at one point.** Register the flag with owner, purpose, category
   and removal date. Evaluate it at the edge of the feature (the route, the component, the
   job entry) through one router function, and pass the decision (or the chosen
   implementation) inward. Scattered `isEnabled()` calls deep in the call stack make both
   testing and removal a hunt.
5. **Keep both paths correct.** Old and new paths must never share half-migrated state:
   if the new path writes a new data shape, the old path must still read it, or the
   rollout needs an expand/contract migration (the `add-db-migration` skill). A flag may
   ADD a security check; it must never switch one off.
6. **Test the combinations that ship.** Run the affected tests with the flag OFF (today's
   production) and ON (the intended release), plus an explicit test that an unset or
   unreadable flag yields the default. You do not need every combination of every flag —
   test the configurations you will actually run.
7. **Make the decision observable.** Record the flag state where behaviour diverges (a
   structured log field or metric label) so an incident can be tied to a rollout; never
   log user data alongside it.
8. **Plan the removal now.** The removal date in the declaration, a note in the evidence,
   and a follow-up the human can file. A flag that has been 100% on for weeks is dead code;
   the `deprecate-and-remove` skill retires it (delete the flag, the losing path and its
   tests together).

## Done when

The flag has one declaration with owner, category and removal date; the default equals
current behaviour and is asserted by a test; tests pass with the flag off and on; the
decision is made at one point; evidence (via the `record-evidence` skill) lists name,
default, owner, removal date and both test runs. On a resume that call is refused: do
not retry; put this, the AC → test map and the smallest-change note in your final
message.

## Stop and escalate when

- The ticket needs percentage rollout, targeting or runtime changes that the repo's
  mechanism cannot do: `request_decision` rather than building a flag service.
- The two paths cannot coexist without a data migration the ticket did not mention:
  `request_decision` with the migration it would need.

## Rules

- One flag system per repo; use the existing one.
- Default = old, safe behaviour, also on evaluation failure.
- Decide at one boundary; no scattered checks; never reuse a flag name.
- Both shipping configurations tested in the same run.
- Work on the delivery branch (the `create-branch` skill verifies); commit, never push.

## Capture lore

This skill is one of the places durable, reusable knowledge naturally surfaces:
**While wiring the flag you learn where flags are declared, how they are named, and how rollouts are actually done here.** That kind of fact is *lore*. Capture it via the **lore-capture
protocol in your brief** (`CLAUDE.factory.md`, step 11 "Memory contribution"):
call the Memory MCP `suggest_lore` once at the close of your work — reusable
conventions, gotchas, decisions, and boundaries only, never per-ticket trivia.

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…