legacy-code
Changing code that is expensive to change safely because behavior is unclear, tests are weak or missing, dependencies are hidden, or runtime/framework setup…
Skill by dekoza
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/dekoza-legacy-code
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/legacy-code
What's inside
- Skill name
legacy-code- Description
- Changing code that is expensive to change safely because behavior is unclear, tests are weak or missing, dependencies are hidden, or runtime/framework setup blocks local feedback. Based on Working Effectively with Legacy Code (Michael Feathers). Covers: characterization tests, seams, dependency breaking, sprout/wrap techniques, incremental risk reduction. Triggers on: "legacy code", "untested code", "change existing code safely", "refactor legacy", "add tests to legacy code", "break dependencies", "no tests", "unclear behavior", "expensive to change", or when touching code with no tests or unclear behavior.
- License
- Unlicense
- Instructions
- 107 lines in SKILL.md · view on GitHub
Files (5)
- SKILL.md
- evals.json · evals/
- dependency-breaking.md · references/
- legacy-work.md · references/
- seam-techniques.md · references/
SKILL.md (first lines)
# Working Effectively with Legacy Code ## When This Skill Loads If you are reading this, the user is working with code that lacks trustworthy tests or has unclear behavior. **Stop and follow this workflow.** Do not start with a rewrite, a broad cleanup, or speculative refactoring. ## Core Principle **Gain control before improving design.** The legacy loop: 1. **Identify** the change point 2. **Characterize** current behavior (write tests that capture what it does today) 3. **Find or create** the smallest useful seam 4. **Break** the dependency that blocks testing 5. **Change** the requested behavior 6. **Refactor** locally — leave the area more testable ## Primary Directive **If a part of the code lacks trustworthy tests, treat it as legacy code.** Before editing, state: - The **requested behavior change** (what should be different) - The **current behavior that must remain** (what must not break) If current behavior is uncertain, **characterize it** — write tests that capture what the code does today, even if the behavior is ugly. Do not silently "fix" behavior you don't understand. ## Decision Rules ### Characterization - Write characterization tests when you don't know whether current behavior is intentional. - Test externally visible behavior first — narrow tests around the slice you're modifying. - If real consumers rely on ugly behavior, capture it. Mark it for clarification, don't silently fix it. - Use sensing variables or temporary probes only to confirm a test reaches the intended path; remove them after use. ### Seams A seam is a place where you can alter behavior without editing in that place. Use the **smallest seam** that unlocks the change: - Constructor injection, parameter injection, extracted method, wrapper around static call, adapter around a framework object, factory indirection, module boundary - Subclass seam only when language constraints leave no better option - Link, import, or preprocessing seams only when ordinary object seams are impractical - Prefer seams that remain useful after the current task over one-off test hooks - Decide whether each seam is for **sensing** (observing behavior), **separation** (substituting a dependency), or both ### Dependency Breaking When code is hard to test, look for these dependency types and break them: | Dependency Type | Examples | Breaking Move | |---|---|---| | **Hidden inputs** | Time, randomness, env vars, thread-local state, globals, singletons | Inject clock, random generator, config | | **Hard outputs** | File writes, network calls, DB writes, process exits, messages | Wrap behind an interface, inject the wrapper | | **Construction problems** | Constructors doing real work, hidden `new`, buried factory calls | Split construction from use, parameterize constructor | | **Static/global reach-through** | Direct static calls, global config access | Encapsulate behind a wrapper, inject the wrapper | ### Sprout and Wrap Techniques When direct edits are too risky: - **Sprout method:** Extract new behavior into a new method. Keep old code mostly untouched. Route to the new method from a small insertion point. - **Sprout class:** Add a focused new collaborator. Delegate from the legacy class. Move behavior over incrementally. - **Wrap method:** Add pre/post behavior around a risky method, or observe effects through a wrapper. - **Wrap class:** Mediate through a new abstraction when the original class is too hard to test directly. ### Keep Changes Separate - **Behavior changes** and **structural refactorings** go in separate commits. - **Characterization tests** (capturing old behavior) and **new behavior tests** stay distinct. - Exploratory restructuring for understanding: do not check it in. ## Trigger Rules - **Uncertain behavior.** When behavior is unclear, consumers may rely on ugly behavior, or a branch is hard to prove — add characterization before changing semantics. - **Expensive setup.** When tests require too much setup or a class can't be instantiated cheaply, break the first real barrier: constructor work, hidden allocation, factory call, global state, static construction. - **Non-determinism.** When time, randomness, environment, thread-local state, files, network, or DB writes block repeatable tests — wrap or inject that boundary. - **Large method/class.** When a method or class defeats local reasoning, sketch effects, find interception or pinch points, extract pure computation first. - **Framework-bound code.** When changing database-heavy, UI, framework, or API-boundary code — separate policy from query/mapping/persistence/handlers. - **Temporary seam.** When a seam is magical, public-for-test, subclass-only, or link/preprocessor-based — add a cleanup obligation. Remove it once safer structure exists. - **Repeated edits.** When repeated edits cluster across several places, remove duplication incrementally under tests instead of launching a broad redesign. - **Rewrite temptation.** When a rewrite feels tempting, choose the smallest sprout, wrap, seam, or characterization step that makes today's requested change safer. ## Forbidden Patterns - **Rewrite as first move.** Do not replace a subsystem before understanding current behavior. - **No-safety change.** Do not change legacy code with no tests or observation strategy. - **Hidden dependency expansion.** Do not add more globals, statics, or ambient context to already hard-to-test code. - **Cosmetic refactoring only.** Do not rename and format while leaving the real dependency knots intact. ## Final Checklist Before finalizing any legacy change: - [ ] Untested area treated as legacy risk? - [ ] Behavior delta and behavior-to-preserve stated? - [ ] Uncertain current behavior characterized? - [ ] Tests close enough and fast enough to diagnose the change? - [ ] Smallest useful seam chosen (sensing vs separation clear)? - [ ] Blocking dependency reduced without expanding hidden dependencies? - [ ] Behavior change, refactoring, and cleanup kept separate? - [ ] Temporary seam has a cleanup path? - [ ] Touched area is more understandable, testable, or changeable than before? ## Reference | File | Use When | |---|---| | [Dependency Breaking](references/dependency-breaking.md) | Choosing which dependency-breaking technique applies to a specific barrier | | [Seam Techniques](references/seam-techniques.md) | Deciding between sprout method, sprout class, wrap method, wrap class, extract-and-override | | [Legacy Workflow](references/legacy-work.md) | Full step-by-step walkthrough of the legacy change loop |
From dekoza/oh-my-slop, Unlicense.
More from dekoza/oh-my-slop
- 0.614score
skill-creator
dekoza
Use when creating or editing SKILL.md files, diagnosing skill-triggering failures, or measuring whether a skill improves agent behavior.
SkillAFreshness: A★ 4Claude Code +9 - 0.609score
resolving-merge-conflicts
dekoza
Use when a git merge or rebase is stopped mid-way with conflicting files.
SkillAFreshness: A★ 4Claude Code +9 - 0.605score
diagnosing-bugs
dekoza
Use when facing a bug with no obvious cause, a performance regression, or 5+ test failures at once.
SkillAFreshness: A★ 4Claude Code +9 - 0.603score
setup-project-skills
dekoza
Configure project workflow bindings, preservation policy and launch gates.
SkillAFreshness: A★ 4Claude Code +9 - 0.574score
enterprise-patterns
dekoza
Use when an enterprise app's infrastructure decisions are in play — where business logic lives, transaction and identity coordination, application-level…
SkillBFreshness: B★ 4Claude Code +9 - 0.574score
construction-craft
dekoza
Use when implementation is blocked by unclear construction prerequisites or tangled routine/data shape, or when system knowledge and artifacts are drifting…
SkillBFreshness: B★ 4Claude Code +9 - 0.574score
domain-driven-design
dekoza
Business complexity, model language, lifecycle rules, or cross-team/system boundaries shape the design more than generic technical organization.
SkillBFreshness: B★ 4Claude Code +9 - 0.574score
production-readiness
dekoza
Services, APIs, jobs, queues, deployment paths, and critical flows that must survive production failures, overload, latency, bad data, and operational mistakes.
SkillBFreshness: B★ 4Claude Code +9 - 0.574score
refactoring-pass
dekoza
Changing existing code structure without intending to change observable behavior.
SkillBFreshness: B★ 4Claude Code +9 - 0.574score
git-guardrails-claude-code
dekoza
Use when the user wants dangerous git commands (push, reset --hard, clean, branch -D, checkout/restore .) blocked by a Claude Code hook before they run — the…
SkillBFreshness: B★ 4Claude Code +9 - 0.574score
codebase-design
dekoza
Use when designing or restructuring a module and reaching for the shared deep-module vocabulary — interface, seam, depth, adapter, leverage, locality — to…
SkillBFreshness: B★ 4Claude Code +9 - 0.574score
data-intensive
dekoza
Systems where correctness depends on data ownership, consistency, durability, replication, partitioning, schema evolution, event flow, replay, or derived-data…
SkillBFreshness: B★ 4Claude Code +9
Signals
- Stars
- 4
- Forks
- 0
- Open issues
- 0
- Last commit (this folder)
- Aug 6, 2026 (2 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- Unlicense
- Repository
- github.com/dekoza/oh-my-slop
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from dekoza
- 0.614score
skill-creator
dekoza
Use when creating or editing SKILL.md files, diagnosing skill-triggering failures, or measuring whether a skill improves agent behavior.
SkillAFreshness: A★ 4Claude Code +9 - 0.609score
resolving-merge-conflicts
dekoza
Use when a git merge or rebase is stopped mid-way with conflicting files.
SkillAFreshness: A★ 4Claude Code +9 - 0.605score
diagnosing-bugs
dekoza
Use when facing a bug with no obvious cause, a performance regression, or 5+ test failures at once.
SkillAFreshness: A★ 4Claude Code +9 - 0.603score
setup-project-skills
dekoza
Configure project workflow bindings, preservation policy and launch gates.
SkillAFreshness: A★ 4Claude Code +9 - 0.574score
construction-craft
dekoza
Use when implementation is blocked by unclear construction prerequisites or tangled routine/data shape, or when system knowledge and artifacts are drifting…
SkillBFreshness: B★ 4Claude Code +9 - 0.574score
documentation-lifecycle
dekoza
Use when documentation must stay truthful as software changes — writing or revising a spec, ADR, runbook, or API/config reference, splitting user-facing docs…
SkillBFreshness: B★ 4Claude Code +9
Cite this page
legacy-code skill. Agent Mart. https://agentmart.dev/skills/dekoza-legacy-code (last updated 2026-10-24)