refactoring-driven-development
RDD is to refactoring/migration what TDD is to greenfield development: a discipline that forces you to lock current behavior in tests before
Open source Open in the app JSON README (API)
About
RDD is to refactoring/migration what TDD is to greenfield development: a discipline that forces you to lock current behavior in tests before you touch a line of code, then rewrite confidently.
Details
- Kind
- Plugins
- Topic
- No topic detected
- Publisher
- gabriel-f-santos
- Origin
- marketplace
- Category
- ferramentas
- Last push
- 2026-05-15T21:55:17Z
- Repository state
- ativo
- License
- MIT
- Added
- 2026-08-30 01:48:58
- Updated
- 2026-08-30 01:48:58
- Origin id
gabriel-f-santos/refactoring-driven-development/refactoring-driven-development
README
# Refactoring-Driven Development (RDD)
> A Claude Code plugin for **rewriting code with parity guarantees**, from spec through characterization tests to a working port.
RDD is to refactoring/migration what TDD is to greenfield development: a discipline that forces you to **lock current behavior in tests before you touch a line of code**, then rewrite confidently.
> **A note on "TDD".** Classical TDD (Beck) writes a failing test for code that doesn't exist yet, then makes it pass. RDD applies the same test-first principle to **legacy code that already exists** — what Michael Feathers called *characterization testing*. Tests describe what the legacy *does*, not what it *should do*. The discipline is the same (red → green → refactor); the starting point differs.
It works equally for:
- **Migration between stacks** — Edge Functions → backend service, Express → NestJS, Rails → Phoenix, monolith → services
- **In-place refactor of a legacy module** — same stack, but cleaner code under a behavior-locking test suite
- **Vendor escape** — moving off a managed service to self-hosted with the same observable contract
- **Language port** — JS → TS, Python 2 → Python 3, etc.
- **Idiomatic improvement** — clean up a parity-correct module after porting, with tests as a safety net
## The 6 skills
**Core pipeline (4 skills):**
```
/rdd-specify-01 → Decide where to migrate: stack, architecture, conventions
/rdd-map-codebase-02 → Survey the legacy, identify modules, propose order
/rdd-specify-03 → Capture business rules from code (single module or batch-all-via-subagents)
/rdd-refactor-04 → Plan characterization tests, lock legacy, port with parity (per module)
```
**Optional (2 skills):**
```
/rdd-improve-05 → After parity, refactor the new code idiomatically — tests guard parity
/rdd-status → Show migration progress across all modules and phases
```
Three skills to **specify and map** (specify-01 → map-codebase-02 → specify-03) before one skill to **refactor with TDD** (refactor-04, which merges test planning + parity port), with one to **polish** (improve-05) and one to **observe** (status). Each reads the artifacts the previous one wrote, so you can stop and resume across sessions. Artifacts live under `rdd/` (configurable).
## Workflow
```
┌──────────────────┐
│ /rdd-specify-01 │ ← decide architecture, framework, conventions
└────────┬─────────┘
▼
rdd/TARGET.md + populates .rdd.yml target block
│
▼
┌────────────────────────┐
│ /rdd-map-codebase-02 │ ← survey legacy with target in mind
└────────┬───────────────┘
▼
rdd/MAP.md
│
▼ (per module, repeat)
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ /rdd-specify-03 │ → │ /rdd-refactor-04 │ → │ /rdd-improve-05 │
└────────┬─────────┘ └────────┬─────────┘ └────────┬─────────┘
▼ ▼ ▼
rdd/<m>/SPEC.md rdd/<m>/TESTS.md (Phase 1) idiomatic code
+ parity-correct code (same green tests
+ green tests on legacy still pass)
AND target
/rdd-status ← run anytime to see where each module is
```
## Principles
1. **Parity first, refactor later.** First port mimics current behavior exactly. Improvement is a separate step, after green tests prove parity.
2. **Decide before mapping.** Target architecture (TD-01, TD-02...) is decided up front and recorded with rationale. Module grouping and test posture flow from those decisions.
3. **Spec before code.** Every module gets a written spec with numbered business rules (BR-01, BR-02...) before any porting.
4. **Characterization, not aspiration.** Tests describe what the system *does*, not what it *should do*. Bug-for-bug parity is the default; intentional behavior changes are tracked explicitly.
5. **Tests that earn their keep.** Every test maps 1:1 to a business rule or observable side effect, written using AC template formulas (`[METHOD] [/path] with [input] returns [status] with [body]`). No snapshot-of-everything, no "controller calls service", no `expect(x).toBeDefined()`.
6. **Validate before generating.** Each skill runs a pre-flight check against its inputs (config consistency, cross-document contradictions, missing decisions) before writing a single line of output.
7. **Resumable execution.** Long-running ports persist state in a progress file (`REFACTOR.progress.md`) and a per-entry-point task list. Stop after each entry point and wait for explicit "Continuar?" — unless the user opted into continuous mode.
8. **Fix-loop discipline.** When tests fail during porting, max 3 focused attempts before escalating. No weakening tests, no skipping, no swallowing errors.
9. **Strangler-style cutover.** New code coexists with legacy behind a feature flag. Cutover is gradual and reversible.
## Installation
Inside Claude Code, add the marketplace and install the plugin:
```
/plugin marketplace add gabriel-f-santos/refactoring-driven-development
/plugin install refactoring-driven-development@gabriel-f-santos
```
Verify the skills are available by typing `/` in Claude Code — you should see `/rdd-specify-01`, `/rdd-map-codebase-02`, `/rdd-specify-03`, `/rdd-refactor-04`, `/rdd-improve-05`, and `/rdd-status`.
Then in any project where you want to use RDD, just invoke `/rdd-specify-01` — the skill auto-creates `.rdd.yml` from the bundled template if it doesn't exist and walks you through filling in legacy + target stack.
## Configuration: `.rdd.yml`
```yaml
legacy:
stack: "Supabase Edge Functions (Deno)"
source: "supabase/functions/"
database: "Postgres (Supabase)"
notes: "RLS policies in migration files; some shared utilities in _shared/"
target:
stack: "NestJS + Fastify"
source: "apps/api/src/"
test_framework: "Vitest"
test_strategy: "integration-first; testcontainers Postgres; mocks only at HTTP boundary"
artifacts_dir: "rdd/"
conventions:
business_rule_prefix: "BR"
module_dir_pattern: "rdd/{module}/"
# Optional: skip /rdd-specify-01 when target stack is already established
# (e.g., in-place refactor of a consolidated codebase). The skill produces
# a minimal TARGET.md focused on conventions.
skip_target: false
```
The skills read this file. **Never** hardcode stack assumptions — write them here once.
## Lightweight mode
The full pipeline is calibrated for **high-stakes work** — production migrations, multi-month rewrites, multi-tenant SaaS. For smaller scopes, skip what doesn't pay for itself:
| Scope | Skip | Why |
|-------|------|-----|
| In-place refactor with target = legacy stack | Set `skip_target: true` | No architectural decisions to make; conventions already established |
| Single small module (≤5 entry points) | Skip `/rdd-map-codebase-02` | Module boundary is obvious; just go straight to `/rdd-specify-03` |
| Pure cosmetic refactor (rename, extract method) inside an already-tested module | Skip everything; use tests directly | RDD overhead doesn't pay off for a 10-minute change |
| Greenfield code | Don't use RDD | RDD assumes legacy code to characterize; for new code use spec-kit or similar |
**Heuristic:** if the change touches >300 lines of legacy code OR has >2 reasonable architectures OR will be in production for >12 months, run the full pipeline. Otherwise, drop phases that don't earn their keep.
## Use cases
### Use case 1: Cross-stack migration
You have a legacy backend (Edge Functions, monolithic Rails app, PHP service, etc.) and want to migrate to a new stack module by module.
```bash
/rdd-specify-01 # decide target stack, architecture, conventions → rdd/TARGET.md
/rdd-map-codebase-02 # survey the legacy with target in mind → rdd/MAP.md
/rdd-specify-03 # batch mode: parallel-spec ALL modules → rdd/<m>/SPEC.md each
/rdd-refactor-04 products # → rdd/products/TESTS.md + parity port (one module at a time)
/rdd-refactor-04 customers # next module
# ... repeat per module
```
`rdd-specify-01`, `rdd-map-codebase-02`, and `rdd-specify-03` (in batch mode) run **once each up front** — they're analysis steps that don't affect production. Then `rdd-refactor-04` runs **per module** because porting must be sequential (parity verification, fix-loop discipline, cutover). Cut over via feature flag when each module is ready.
If you prefer to spec one module at a time (e.g., to interview tribal knowledge per module), invoke `/rdd-specify-03 <module>` instead — same skill, single-module mode.
### Use case 2: In-place refactor
Same stack, but a module accumulated cruft and you want to rewrite it cleanly. The same flow works — `legacy` and `target` in `.rdd.yml` point to the same stack but different source directories (or branches).
### Use case 3: Vendor escape
Moving off a SaaS dependency. Treat the old vendor's API as `legacy`. Treat your replacement as `target`. Run the flow per consumer surface.
### Use case 4: Idiomatic improvement after porting
You ran `/rdd-refactor-04 products` and the new module is parity-correct but ugly — direct copy of legacy structure, repeated code, no value objects. Run `/rdd-improve-05 products` to clean up incrementally. The same characterization tests from `/rdd-refactor-04` guard parity: any refactor that breaks observable behavior shows up immediately.
```bash
/rdd-improve-05 products # → rdd/products/IMPROVE.md (refactor plan), then incremental refactors
```
### Use case 5: Tracking progress across many modules
For a multi-module migration spanning weeks or months, you need a quick way to see where each module is. Run `/rdd-status` anytime:
```bash
/rdd-status # reads existing artifacts, prints a per-module phase table
```
No persistent state file — `/rdd-status` infers progress from what's on disk.
## What this is not
- **Not a code generator from scratch.** RDD assumes you have working legacy code to characterize. For greenfield work, use spec-kit or similar.
- **Not a linter or autofix.** It coordinates a human + LLM workflow; it doesn't blindly transform code.
- **Not microservices-specific.** The Strangler Fig pattern that inspired part of this is *one* cutover strategy among many.
## Anti-pattern: tests that don't earn their keep
RDD has strong opinions on what tests to write — and not write — during refactoring. Summary:
| Write | Don't write |
|--------------------------------------|------------------------------------------|
| End-to-end use cases from spec | "Controller calls service" |
| Domain invariants | DTO validation already enforced by lib |
| Observable error paths (403, 422) | Snapshots of mutable JSON |
| Idempotency of webhooks | `expect(x).toBeDefined()` without intent |
| Property-based for calculations | Mock-of-mock-of-mock |
| Boundary cases discovered in code | Tests that break on every refactor |
If a test breaks during refactor *without changing observable behavior*, it was testing implementation. Delete it.
## Contributing
PRs welcome. Especially:
- Examples of RDD applied to other migration scenarios (add to `examples/`)
- Improvements to skill prompts based on real-world usage
- Translations of the skill prompts (current: English; the methodology is language-agnostic)
## License
MIT