# Shiva

> Refactoring rules — safe transformation of existing code without behavior change. Use when refactoring, restructuring, cleaning up code, paying down tech debt, or planning a rewrite.

- Skill: `arjuncrevathi/shiva` (Agent Skill)
- Install (CLI): `npx skillmds@latest add arjuncrevathi/shiva`
- Raw SKILL.md: https://api.skillmd.com/api/skills/arjuncrevathi/shiva/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: arjuncrevathi (https://skillmd.com/u/arjuncrevathi)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/arjuncrevathi/shiva

---


# Shiva — The Transformer (Refactoring)

Shiva destroys only to rebuild: every transformation is deliberate, tested, and reversible.

## Prerequisites — never skip

- Never refactor code without tests covering current behavior. No tests? Write characterization tests first: capture what the code actually does (including its bugs), then refactor against them.
- Confirm the code is worth transforming: it changes often, or it blocks a feature. Stable code nobody touches stays as it is.
- Run the full test suite green before touching anything. That is your baseline.

## The rules of transformation

- Behavior-preserving only. A refactor changes structure, never observable behavior. If you found a bug, fix it in a separate commit/PR first.
- Never mix refactoring with feature work. One PR = one refactor. Reviewers cannot verify "moved AND changed" diffs.
- Small reversible steps: rename, extract, inline, move — one mechanical step at a time, tests green after each. Commit at every green state so any step can be reverted alone.
- Prefer automated transforms (IDE rename/extract, `ruff --fix`, `jscodeshift`, `ast-grep`) over hand-editing — they don't typo.
- Keep the old and new paths compilable at every commit. Long-lived "big bang" refactor branches rot; land incrementally behind the same interface.

## Big rewrites — strangler fig

- Never rewrite a live system in place. Put a seam (router, facade, adapter) in front, build the new implementation beside the old, and migrate callers one by one.
- Route a small percentage of traffic to the new path first; compare outputs (shadow mode) before cutting over.
- Delete the old path only when zero callers remain — then delete it completely, same week. A strangler fig that never strangles is double the debt.

## Deleting dead code

- Delete aggressively: unused functions, unreachable branches, commented-out blocks, feature flags past their expiry, exports with no importers.
- Verify death first: `grep`/`rg` across all repos, check dynamic call sites (getattr, string dispatch, DI containers), check production logs/metrics for the endpoint.
- Deletion-only PRs merge fast — keep them separate from other changes.

## When NOT to refactor

- Right before a deadline or during an incident — stabilize first.
- Code you don't understand yet — read, test, and instrument before reshaping.
- Working code slated for deletion or replacement within a quarter.
- "While I'm here" drive-by refactors inside a feature PR — file an issue instead.

## Measure before/after

- Record the motivating metric before starting: cyclomatic complexity, test runtime, p95 latency, lines touched per change, onboarding questions.
- After landing, confirm the metric moved. A refactor that improves nothing measurable was churn.

## Before every refactor PR — checklist

- [ ] Tests (or new characterization tests) cover current behavior and pass
- [ ] Diff contains zero behavior changes and zero feature work
- [ ] Steps are small, each commit green and independently revertible
- [ ] Dead code found along the way is deleted (own PR if large)
- [ ] Before/after metric recorded in the PR description

