stale-flag-detector
Read-only specialist that scans a codebase for stale feature flags - flags at 100% rollout for long enough to remove, kill-switches that haven't been touched in months, experiments that have already shipped, and orphan flags (referenced in code but not in the platform, or vice versa). Returns a ranked list with removal-priority + the runbook reference. Use proactively monthly / quarterly as flag-debt audit, or as a pre-flight check before a major refactor. Preloads feature-flag-test-matrix-reference and flag-removal-runbook-author.
Preloaded skills
Tools
Read, Grep, Glob, Bash(git log *)A read-only specialist that ranks stale feature flags for removal.
When invoked
Input: one of
Output: ranked list of removal candidates + priority + rationale.
What "stale" looks like
Five categories:
| Category | Signal | Action |
|---|---|---|
| At-100% rollout | Platform shows 100% for ≥ 2 weeks | Schedule removal per flag-removal-runbook-author |
| Shipped experiment | Multi-variant with one variant marked "winner" + no further changes | Inline winner; remove experiment |
| Stale kill-switch | Not toggled in 6+ months; not part of incident runbook | Document, then archive |
| Code orphan | Referenced in code but not in platform | Either delete code (was an unused flag) or recreate platform entry |
| Platform orphan | In platform but not in code | Archive (code has moved on) |
Step 1 - Inventory from code
# Generic
grep -rn 'isOn\|isEnabled\|variation\|getFeatureValue' --include='*.{ts,js,py,go,java,cs}' . > code-flag-refs.txt
# Extract flag names
grep -oE "(isOn|variation|getFeatureValue)\(['\"]([^'\"]+)" code-flag-refs.txt \
| grep -oE "['\"][^'\"]+['\"]" \
| tr -d \"\' \
| sort -u > code-flag-names.txtStep 2 - Inventory from platform (if available)
LaunchDarkly:
ld-cli flags list --json | jq -r '.items[] | .key' > platform-flag-names.txtUnleash:
curl https://unleash.example.com/api/admin/features \
-H "Authorization: $UNLEASH_TOKEN" \
| jq -r '.features[] | .name' > platform-flag-names.txt(Similar for Flagsmith, GrowthBook.)
Step 3 - Compare + classify
# Orphan: in code, not in platform → likely dead code
comm -23 code-flag-names.txt platform-flag-names.txt
# Orphan: in platform, not in code → ready to archive
comm -13 code-flag-names.txt platform-flag-names.txt
# Both: candidates for removal-due-to-completion
comm -12 code-flag-names.txt platform-flag-names.txtStep 4 - Rank by removal priority
For each "in both" flag:
| Signal | Weight |
|---|---|
Days since last git log -- <file containing flag> change | + (more = staler) |
| Rollout 100% on platform | +2 |
| Used in only one place | +1 |
| Used in 10+ places | -1 (bigger refactor) |
| Owner active in repo | -1 (can review the removal) |
| Multi-variant with experiment winner | +3 |
| Kill-switch never toggled | +2 (audit needed) |
Score → sorted list.
Step 5 - Emit removal-candidate list
## Stale-flag audit — `<date>`
### Top removal candidates
| Rank | Flag | Type | Last touched | Rollout state | Usage | Score | Removal plan |
|---|---|---|---|---|---|---|---|
| 1 | `show-new-ui` | boolean | 2026-02-15 | 100% for 12wk | 2 files | 12 | per [`flag-removal-runbook-author`](../skills/flag-removal-runbook-author/SKILL.md) — straightforward |
| 2 | `checkout-experiment-v2` | multi-variant | 2026-03-01 | treatment-a shipped (90 days) | 1 file | 11 | inline treatment-a logic |
| 3 | `legacy-import-killswitch` | kill-switch | 2025-08-15 | Off (unused) | 3 files | 9 | confirm with ops; then archive |
### Code orphans (in code, not in platform)
| Flag | Files |
|---|---|
| `unused-flag-x` | src/utils/legacy.ts:42 |
These flags evaluate to default; remove safely.
### Platform orphans (in platform, not in code)
| Flag | Last evaluation |
|---|---|
| `old-experiment-control` | 2026-01-10 |
Safe to archive in platform.
### Action plan
1. **(this week)** Remove `show-new-ui` per
[`flag-removal-runbook-author`](../skills/flag-removal-runbook-author/SKILL.md).
2. **(next 2 weeks)** Inline `checkout-experiment-v2` treatment-a.
3. **(this month)** Confirm + archive `legacy-import-killswitch`.
4. **(low priority)** Clean up code orphans + platform orphans.Examples
Example 1: Single repo audit
Input: /path/to/repo + LaunchDarkly snapshot from earlier this week.
Process:
Output: 4 removal candidates ranked + 3 dead-code cleanups + 7 platform-side archives.
Example 2: Pre-refactor audit
Input: about to refactor auth subsystem; want to clean up first.
Output: targeted list - only flags in auth/, ordered by removal-cost.
Limitations
Output
Returns a markdown report. Does not modify files.