Skip to content
This repository was archived by the owner on Apr 11, 2026. It is now read-only.

Commit df68502

Browse files
z23ccclaude
andcommitted
feat: add deprecation and migration skill
Stack-agnostic skill for managing deprecation workflows — assessment, replacement, migration, and clean removal. Inspired by agent-skills. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent d626eb2 commit df68502

1 file changed

Lines changed: 194 additions & 0 deletions

File tree

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
name: flow-code-deprecation
3+
description: "Use when removing, replacing, or sunsetting features, APIs, modules, or dependencies in any codebase"
4+
---
5+
6+
# Deprecation and Migration
7+
8+
## Overview
9+
10+
Code is a liability, not an asset — every line carries ongoing maintenance cost. This skill enforces a disciplined process for deprecating and removing code that no longer earns its keep, ensuring consumers are migrated safely before anything is removed.
11+
12+
## When to Use
13+
14+
- Replacing an old system, API, library, or module with a new one
15+
- Sunsetting a feature, CLI command, or config option that's no longer needed
16+
- Consolidating duplicate implementations into a single path
17+
- Removing dead code that nobody owns but everybody depends on
18+
- Planning the lifecycle of a new system (deprecation planning starts at design time)
19+
- Deciding whether to maintain a legacy system or invest in migration
20+
21+
**When NOT to use:**
22+
- Routine refactoring that doesn't remove public interfaces — use standard refactoring
23+
- Adding new features alongside old ones without removing anything
24+
- Version bumps that don't change or remove behavior
25+
- Bug fixes in legacy code you intend to keep
26+
27+
## The Deprecation Decision
28+
29+
Before deprecating anything, answer these questions:
30+
31+
```
32+
1. Does this system still provide unique value?
33+
→ If yes, maintain it. If no, proceed.
34+
35+
2. How many consumers depend on it?
36+
→ Quantify: grep for imports, check API call logs, review dependency graphs.
37+
38+
3. Does a replacement exist?
39+
→ If no, BUILD THE REPLACEMENT FIRST. Never deprecate without an alternative.
40+
41+
4. What's the migration cost per consumer?
42+
→ If automatable (codemod, sed, script), do it yourself (the Churn Rule).
43+
→ If manual and high-effort, weigh against ongoing maintenance cost.
44+
45+
5. What's the cost of NOT deprecating?
46+
→ Security risk, engineer time, dependency rot, onboarding friction.
47+
```
48+
49+
If answers 1=no, 3=yes, and 5 > 4, proceed with deprecation.
50+
51+
## Advisory vs Compulsory Deprecation
52+
53+
| Type | When to Use | Mechanism |
54+
|------|-------------|-----------|
55+
| **Advisory** | Old system is stable, migration is optional | Warnings, documentation, nudges. Consumers migrate on their own timeline. |
56+
| **Compulsory** | Security risk, blocks progress, or maintenance cost is unsustainable | Hard deadline. Old system removed by date X. Provide migration tooling. |
57+
58+
**Default to advisory.** Use compulsory only when risk or cost justifies forcing migration. Compulsory deprecation requires providing migration tooling, documentation, and support — you cannot just announce a deadline.
59+
60+
## Core Process
61+
62+
### Phase 1: Assess Impact
63+
64+
1. **Inventory all consumers** — grep for imports, API calls, config references, CLI invocations. Miss nothing.
65+
2. **Map the dependency graph** — direct consumers and transitive dependents. Hyrum's Law: with enough users, every observable behavior becomes depended on, including bugs and timing quirks.
66+
3. **Quantify maintenance cost** — security vulnerabilities, test failures, onboarding friction, dependency update burden.
67+
4. **Document the assessment:**
68+
```
69+
Deprecated: <component name>
70+
Consumers: <count and list>
71+
Maintenance cost: <specific burden>
72+
Replacement: <name or "to be built">
73+
Migration type: advisory | compulsory
74+
```
75+
76+
### Phase 2: Build the Replacement
77+
78+
**Do NOT announce deprecation until the replacement is production-proven.**
79+
80+
1. **Cover all critical use cases** of the old system
81+
2. **Write a migration guide** with concrete steps and examples
82+
3. **Prove it in production** — not just "theoretically better"
83+
4. **Verify behavioral parity** on edge cases consumers depend on
84+
85+
### Phase 3: Announce and Document
86+
87+
Create a deprecation notice:
88+
89+
```
90+
## Deprecation Notice: <ComponentName>
91+
92+
Status: Deprecated as of <date>
93+
Replacement: <NewComponent> (see migration guide)
94+
Removal date: Advisory — no hard deadline | Compulsory — <date>
95+
Reason: <specific maintenance burden or risk>
96+
97+
### Migration Steps
98+
1. Replace <old import/call> with <new import/call>
99+
2. Update configuration (see examples)
100+
3. Run migration verification: <command>
101+
```
102+
103+
Place notices where consumers will see them: inline warnings, changelogs, documentation headers.
104+
105+
### Phase 4: Migrate Consumers
106+
107+
For each consumer:
108+
109+
1. **Identify all touchpoints** with the deprecated system
110+
2. **Update to the replacement** — provide codemods or scripts where possible
111+
3. **Verify behavior matches** — tests, integration checks, manual validation
112+
4. **Remove references** to the old system
113+
5. **Confirm no regressions**
114+
115+
**The Churn Rule:** If you own the infrastructure being deprecated, you are responsible for migrating your users — or providing backward-compatible shims. Do not announce deprecation and leave users to figure it out.
116+
117+
### Phase 5: Remove Old Code
118+
119+
Only after all consumers have migrated:
120+
121+
1. **Verify zero active usage** — metrics, logs, dependency analysis, grep
122+
2. **Remove the code** — implementation, types, exports
123+
3. **Remove associated artifacts** — tests, documentation, configuration, feature flags
124+
4. **Remove deprecation notices** — they served their purpose
125+
5. **Run full verification:**
126+
```bash
127+
$FLOWCTL guard
128+
```
129+
130+
### Phase 6: Verify Clean Removal
131+
132+
1. **Search for orphaned references** — stale imports, dead config keys, broken links in docs
133+
2. **Run the full test suite** — no failures from missing code
134+
3. **Check build artifacts** — no phantom exports or dangling symbols
135+
4. **Confirm documentation is updated** — no references to removed components
136+
137+
For planning migration work across multiple tasks, use `/flow-code:plan`.
138+
139+
## Migration Patterns
140+
141+
### Strangler Pattern
142+
Run old and new in parallel. Route traffic incrementally from old to new. Remove old when it handles 0%.
143+
144+
### Adapter Pattern
145+
Wrap old interface around new implementation. Consumers keep using the old interface while the backend migrates underneath.
146+
147+
### Feature Flag Migration
148+
Use feature flags to switch consumers from old to new one at a time. Roll back instantly if issues arise.
149+
150+
## Zombie Code
151+
152+
Code that nobody owns but everybody depends on. Signs:
153+
- No commits in 6+ months but active consumers exist
154+
- No assigned maintainer
155+
- Failing tests nobody fixes
156+
- Dependencies with known vulnerabilities nobody updates
157+
158+
**Response:** Either assign an owner and maintain it, or deprecate it with a concrete migration plan. Zombie code cannot stay in limbo.
159+
160+
## Common Rationalizations
161+
162+
| Excuse | Reality |
163+
|--------|---------|
164+
| "It still works, why remove it?" | Working code without maintenance accumulates security debt and complexity. Cost grows silently until it's a crisis. |
165+
| "Someone might need it later" | If needed later, it can be rebuilt with better design. Keeping unused code "just in case" costs more than rebuilding. |
166+
| "No one uses this anymore" | Did you verify that with grep, metrics, and logs? Undocumented consumers are the norm, not the exception. |
167+
| "We can remove it later" | Later never comes. Every month you delay, more consumers may adopt the deprecated path. |
168+
| "Breaking changes are fine for a major version" | A major version bump does not excuse removing things without migration paths. Semver is a signal, not a license to break users. |
169+
| "The migration is too expensive" | Compare migration cost to 2-3 years of ongoing maintenance. Migration is almost always cheaper long-term. |
170+
| "Users will migrate on their own" | They won't. Provide tooling, documentation, and support — or do the migration yourself (the Churn Rule). |
171+
| "We can maintain both indefinitely" | Two systems doing the same thing means double the maintenance, testing, documentation, and onboarding cost. |
172+
173+
## Red Flags
174+
175+
- Deprecating a system with no replacement available or proven
176+
- Deprecation announcement with no migration guide, tooling, or timeline
177+
- "Soft" deprecation that has been advisory for months or years with no progress
178+
- Removing code without verifying zero active consumers first
179+
- New features added to a system already marked deprecated (invest in the replacement instead)
180+
- Zombie code with no owner and active consumers left in limbo
181+
- Deprecation without quantifying current usage
182+
183+
## Verification
184+
185+
After completing a deprecation cycle, confirm:
186+
187+
- [ ] Deprecation decision documented with consumer count, maintenance cost, and replacement name
188+
- [ ] Replacement is production-proven and covers all critical use cases
189+
- [ ] Migration guide exists with concrete steps, examples, and verification commands
190+
- [ ] All active consumers migrated (verified by grep, metrics, or logs — not assumption)
191+
- [ ] Old code, tests, documentation, and configuration fully removed
192+
- [ ] No orphaned references to the deprecated system remain in the codebase
193+
- [ ] `$FLOWCTL guard` passes after removal
194+
- [ ] Deprecation notices removed (they served their purpose)

0 commit comments

Comments
 (0)