Skip to content
Back to skills

Flagrm Remove

ASecurity

Use when the user asks to remove, retire, deprecate or clean up a feature flag or feature toggle, says a flag is fully rolled out, or runs /flagrm-remove <flag>, in a repository with a flagrm.config.yaml. Works for Angular, .NET and other stacks: IFeatureManager, [FeatureGate], appsettings FeatureManagement, LaunchDarkly-style calls, flags objects, enums, signals, *ngIf/@if templates.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 9, 2026
ai-agentsgoangulardockergitapi

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned November 10, 2026

npx -y skills add dino-cosic/flagrm --skill flagrm-remove --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Flagrm Remove?

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

Security grade badge for Flagrm Remove
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dino-cosic-flagrm-remove/badge)](https://www.skillsdirectory.com/skills/dino-cosic-flagrm-remove)

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: flagrm-remove
description: >
  Use when the user asks to remove, retire, deprecate or clean up a feature flag
  or feature toggle, says a flag is fully rolled out, or runs /flagrm-remove <flag>,
  in a repository with a flagrm.config.yaml. Works for Angular, .NET and other
  stacks: IFeatureManager, [FeatureGate], appsettings FeatureManagement,
  LaunchDarkly-style calls, flags objects, enums, signals, *ngIf/@if templates.
---

# Remove a feature flag

**The flag is permanently ON.** Keep the ON path, delete the OFF path and everything only it used. Behavior with the flag ON must not change.

You find and edit the code. `flagrm` records the state before you start and
decides when you are done: **done means `flagrm verify <flag> --json` exited 0.**
Run it as `npx --no-install flagrm`, one command per call, no `||` (plain `npx flagrm` is another package).

Several flags (`/flagrm-remove A B C`): read [batch.md](batch.md) first; it runs this workflow once per flag.

## 1. Preconditions

- `flagrm doctor` must not warn about uncommitted files (flagrm's own setup files and `exclude`d paths don't count). Otherwise ask the user to commit or stash.
- No `flagrm.config.yaml`: run `flagrm init` and fill in project paths and build/test commands with the user.
  Its doctor reports a missing SDK, `cargo` or Docker: show it. For `cargo`/Docker, offer `flagrm scope`; `--write` only on a yes.
- `flagrm list --json`: find the flag in `flags[]`. Not there: show the closest names and ask.
- `state` is `off`, `mixed` or `conditional`: name the environments in `config[]` that change and get a yes, or stop.
  `unconfigured` (set in a flag service): with `launchdarkly:` in the config, `flagrm stale <flag> --json`; verdict `remove` confirms ON, another verdict: stop and show its `reasons`. No section, or `stale` exits non-zero (show its message): ask if it is ON everywhere. The removal request is not that answer.
- Read `CLAUDE.md` or `AGENTS.md` if present, for conventions and build commands.

## 2. Baseline

`flagrm baseline <flag> --json` records the git commit, build and test results and the flag's `names[]`.
A `checks[]` entry with a non-zero `exitCode` and a `failure`: a setup problem. Show the user `failure.message` (and `flagrm scope`); once fixed, rerun with `--force`.
Without `failure`: a build, stop. Tests: stop if the failures (`results.failedTests`) could cover the flag's code; else ask the user to accept them as known, and on a yes run `flagrm baseline <flag> --accept failures`.

## 3. Find every usage

- Grep for each name in `names[]`: code, templates, config and tests. `parameterizedTests[]` are test calls passing ON/OFF.
- `suggestedNames[]`: values of the flag with generic names. Record each that carries only this flag, a local, parameter or field with `--file <its file>` (repeat `--file` for each file; a component's template is added for you).
- Follow the value further: a method or property returning it, a field or local holding it, a parameter
  it's passed as, a DI-registered bool. Record each so `verify` checks it, then grep for it:
  `flagrm baseline <flag> --name IsNewCheckoutEnabledAsync --kind wrapper` (`--kind alias` for a constant like `Flags.NewCheckout`).

## 4. Remove

Read `patterns.md` in this skill's directory when a case is unclear.

- Condition: keep the ON branch, delete the OFF branch, drop the check.
  `a && flag` → `a`, `a || !flag` → `a`. Never touch other flags.
- Wrapper: replace each call with `true` and simplify, then delete the wrapper, its interface member and DI registration.
- Passed as a parameter: pass `true` and simplify the callee. Once no caller
  passes anything else, remove the parameter and the argument at every caller.
- Code only the OFF path used (methods, classes, fields, constructor parameters,
  DI registrations, imports/usings, files): delete it. Keep what anything else uses.
- Definition and config: remove the constant, enum member or flags-object key,
  and the key in every environment's config file. Remove a section left empty.
  Keep a key the service sends to other apps (a known-flags list behind a config endpoint): they'd read OFF.
- Tests: delete tests of the OFF path. In the others, remove the flag setup
  (mocks, spies, overrides) and drop the flag from the test name. A test
  parameterized over ON/OFF keeps only the ON case.
- Keep the flag system itself (the flag service or client and its generic methods), public API
  of a library package, and anything that also defines other flags. Mention them in your report.

## 5. Verify until it passes

`flagrm verify <flag> --json`. Fix every check with `status: "fail"`, run it again.

| Check | Fix |
|---|---|
| `leftovers` | Remove each reference listed. A comment is a warning: reword or delete it. A test checking text you deleted tests the OFF path: delete it. ON text no test checks: say so in your report |
| `dead-code` | Delete what the removal left unused. A declaration "referenced only where it is declared" (warning): delete it if only the OFF path used it; else say why it stays |
| `build` | Fix the error your edit caused; don't touch unrelated code. `tsc` skips templates: grep `.html` for each member you removed or renamed |
| `tests` | A new failure means ON behavior changed: fix the edit, not the test. Known failures (failed at the baseline) only warn. A test listed as no longer running (`unexplained`) must be one you removed on purpose: say why. A changed test file whose tests didn't run: run them yourself and report it |
| `lint` | Fix what your edit caused. An already-failing lint fails only on new error lines: fix those; other new lines it lists only warn |
| `coverage` | Tell the user which changed files no command checks; don't add or change commands yourself |

Exit 2 is a usage or config error: read the message. `--skip build,tests,lint,coverage` is fine for a quick check in between; only a full run counts, and the Stop hook won't let you finish on one with `--skip`. After three failed attempts on one check, show the user the findings. Don't run code generators or formatters after the passing verify; if you must, verify again.

## 6. Hand back

1. `flagrm verify <flag> --md` on the final tree (it reuses the passing build, test and lint runs; edit nothing after it): show its output exactly as printed; don't reword it or change its numbers. It must pass: the Stop hook checks it.
2. **Notes**, 3–5 lines: what you kept on purpose, each remaining warning with its reason, follow-ups in the flag service. If `state` wasn't `on` and nobody confirmed ON, start with "Assumed ON everywhere". End with: optional, for an independent review, run `/flagrm-review <flag>` in a new session.
3. The commit message:

<!-- commit-message:start -->
**Proposed commit message**, in a code block:

```
chore: remove <flag> feature flag

<one or two sentences: which path stays and what was deleted>
```

- Follow the repository's convention instead when `git log --oneline -10` shows a different one.
- A ticket in the branch name (`feature/feat-24586`): add it the way the log does (`#24586`, `FEAT-24586`), else `(#24586)` after the subject.
- Wrap the body at 72 columns.
<!-- commit-message:end -->

Commit only when the user asked (in a batch: their answer at the start).

## Rules

- Never lift code out of the OFF path into live code.
- Match the file's formatting; don't refactor unrelated code.
- Never edit `.flagrm/`. Rerun `flagrm baseline <flag>` only with `--name`, or with `--force` before your first edit (it refuses after).
- Never `--skip` a failing check, and never change a test's expected value or the build, test or lint commands or `covers` to pass. If the user changes the config mid-removal (say, to leave out tests that need services), run `flagrm baseline <flag> --accept config` once they confirm.
- `baseline` and `verify` reuse a passing verify's build, test and lint results on the same tree and commands. If the user changed the machine (SDK, Docker, services) since, add `--no-reuse`.

Files in this skill

  • SKILL.md6.1 KB
  • patterns.md3.5 KB

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.

View all in ai-agents →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.