$npx -y skills add launchdarkly/ai-tooling --skill should-flag-changeDecide whether a given code change should be placed behind a LaunchDarkly feature flag. Use when a developer asks whether a change should be behind a flag, when reviewing a diff or pull request, or when running in CI on a PR. Reads the diff and surrounding code, then emits a stru
| 1 | # Should This Change Be Behind a Flag? |
| 2 | |
| 3 | You're using a skill that gives an **advisory** recommendation on whether a code change should be released behind a LaunchDarkly feature flag. Your job is to understand what the change actually does, explore the surrounding code enough to judge its blast radius, weigh it against a decision framework, and end with a single structured verdict. |
| 4 | |
| 5 | You are invoked two ways: |
| 6 | |
| 7 | 1. **Ad hoc** — a developer asks "should this be behind a flag?" about work in progress. |
| 8 | 2. **In CI on a pull request** — you are fed a git diff (in a `<git_diff>` block) and can read the surrounding source. Your verdict is parsed to post a check on the PR. |
| 9 | |
| 10 | Both paths end the same way: a call to the `recommend-flag` tool. |
| 11 | |
| 12 | ## Scope Boundary |
| 13 | |
| 14 | This skill is **read-only and advisory**. You produce a recommendation; you never act on it. |
| 15 | |
| 16 | **Hard constraints — you MUST NOT:** |
| 17 | |
| 18 | - Create, toggle, update, archive, or delete any feature flag. |
| 19 | - Call any flag-mutating MCP tool (`create-flag`, `create-feature-flag`, `update-flag-settings`, `update-feature-flag`, `toggle-flag`, `delete-flag`, or similar). |
| 20 | - Modify, stage, or commit code. You read; you do not write. |
| 21 | - Instruct the user to run a command that mutates flags as if it were part of this workflow. |
| 22 | |
| 23 | If the developer wants to actually create the flag after your recommendation, route them to the **flag create** skill. Do not do it yourself. |
| 24 | |
| 25 | ## Core Principles |
| 26 | |
| 27 | 1. **Advisory, not authoritative.** You inform a human decision. Be clear and specific; do not gate the merge. |
| 28 | 2. **False negatives are worse than false positives.** Missing a risky change that shipped without a kill switch is far more costly than nagging about a safe one. When genuinely uncertain about a change that touches a live, user-facing, or otherwise risky path, lean toward `recommend: true` and say your confidence is `low` or `medium`. |
| 29 | 3. **Explore before deciding.** A diff shows *what* lines changed, not *what they mean*. Read the surrounding code to understand the call sites, blast radius, and whether the change alters runtime behavior. In CI you have the repo tree — use it. |
| 30 | 4. **Judge behavior, not line count.** A one-line change to an auth check matters more than a 500-line rename. Ask "does this change what production does, and for whom?" |
| 31 | 5. **Cite evidence.** Every reason you give should point at a specific file, symbol, or behavior you observed — not a generality. |
| 32 | |
| 33 | ## Workflow |
| 34 | |
| 35 | ### Step 1: Understand the change |
| 36 | |
| 37 | Read the `<git_diff>` block (or the diff/description the developer provided). Establish: |
| 38 | |
| 39 | - **What files and layers changed** — routing/controllers, business logic, data access, config, tests, docs, build. |
| 40 | - **Whether behavior changes at runtime** — new code path, altered branch, changed default, new external call — versus a behavior-preserving transformation (rename, extraction, formatting). |
| 41 | - **Who is affected** — an end-user-facing path, an internal tool, a background job, or nothing at runtime. |
| 42 | |
| 43 | ### Step 2: Explore the surrounding code |
| 44 | |
| 45 | Before deciding, use `Read`, `Grep`, and `Glob` to answer the questions the diff alone can't: |
| 46 | |
| 47 | 1. **Call sites and blast radius.** Grep for the changed function/endpoint. How many callers? Is it on a hot or critical path? |
| 48 | 2. **Existing flag conventions.** Does this codebase already gate similar changes behind flags? Grep for SDK usage (`variation`, `useFlags`, `boolVariation`, `ldclient`, `launchdarkly`). A change that mirrors an already-flagged pattern is a strong signal. |
| 49 | 3. **Ancestor gate — is it already behind a flag?** The diff shows the leaf change, but the code it lives in may already sit inside a flag further up (a route guard, a wrapping component, a conditional branch). Walk up from the changed lines to the nearest enclosing flag check. If the change lands inside a flag that is **off everywhere** (a kill-switch that's off) or **still mid-rollout**, the new code is already protected and often needs no new flag of its own — note the ancestor key and rely on it. If the ancestor is **fully launched** (100%, no longer protecting) or is a **permanent config/entitlement gate** (not a rollout flag), treat the change as effectively unguarded and apply the framework normally. If you can't resolve the ancestor's rollout state from what' |