# Improve Code

> Refactor code for human readability and agent navigation. Use when module boundaries, naming, coupling, or structure make a scoped change difficult.

- Skill: `cskwork/improve-code` (Agent Skill, multi-file: 6 files)
- Install (CLI): `npx skillmds@latest add cskwork/improve-code`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cskwork/improve-code/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: cskwork (https://skillmd.com/u/cskwork)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/cskwork/improve-code

---


# Improve Code

Reshape a target so that making one correct change needs less context. The bar is dual and non-negotiable: an **AI agent** and a **human** must both be able to find the behavior, change one bounded place, and verify it — without reading the whole system.

Work only where a **smell** is present and the fix passes the **net-complexity gate** (it removes more to understand than it adds). Absent a smell and a named payoff, leave the code alone — a patch that fights the existing structure is a defect, not an improvement.

Three leading ideas carry the whole skill:

- **Deep module** — a small, stable interface hiding a large implementation. The opposite, a **shallow module** (interface nearly as complex as the code behind it: thin wrappers, pass-through methods), adds cost without hiding complexity. Deepen shallow things; do not shred deep things into fragments.
- **Blast radius** — how many places one change must touch. Good structure keeps it to one place (high **locality**).
- **Seam** — a point where behavior can be substituted (inject a fake for the clock, network, filesystem, or DB). Seams are where tests attach and where internals get rewritten safely.

Consult the reference relevant to the current decision:

- [PRINCIPLES.md](reference/PRINCIPLES.md) — the full smell catalog, vocabulary, and principle set. Diagnosing (Step 3) and naming (Step 7).
- [VISUAL-DIFF.md](reference/VISUAL-DIFF.md) — how to render and open the as-is → to-be visual. Proposing (Step 4).
- [SAFE-REFACTOR.md](reference/SAFE-REFACTOR.md) — the discipline and the move catalog. Testing and changing safely (Steps 5–6).
- [DOCS.md](reference/DOCS.md) — which doc to write, and how much. Documenting (Step 7).

## Steps

Use the steps as a workflow; reuse established scope and evidence instead of repeating completed work.

### 1. Set the goal

Ask the user what to improve and why, unless the conversation has already made it explicit. Draw out four things and nothing more:

- **Target** — the file, module, or flow in scope.
- **Payoff** — the pain to relieve: hard to read, hard to change, hard to test, or hard for an agent to navigate.
- **Constraints** — must behavior and the public interface stay identical? Any area that is off-limits?
- **Definition of done** — the observable state that ends the task.

For a broad request, inspect the code and recommend a bounded target. Ask only when a material goal or constraint remains unresolved.

**Done when:** you can state the goal back in one short paragraph (target + payoff + constraints + definition of done) and it matches the user’s instruction or existing confirmation.

### 2. Explore and pin the ground truth

Read before proposing. Map the target — what it calls, what depends on it — using whatever code-navigation tools this environment offers: a codebase knowledge graph or language server when present, otherwise plain search and read. Use a bounded read-only subagent only when independent exploration reduces total work and delegation is available and authorized. State, in plain language, what the target does today.

Run the relevant existing checks and record the baseline. Separate pre-existing failures from regressions; stop only when they prevent meaningful verification of this target.

**Done when:** you can describe the target's current behavior in plain language, and the relevant baseline and any verification limitations are recorded.

### 3. Diagnose against the principle set

Walk the target for **smells** from [PRINCIPLES.md](reference/PRINCIPLES.md) — shallow modules and pass-through methods, hidden coupling (global state, temporal ordering, control flags), strong **connascence** crossing a boundary, primitive obsession, deep nesting, junk-drawer or layer-first structure, inconsistent naming, and stale or contradictory docs.

For every candidate fix, apply the **net-complexity gate**: does it remove more for a reader to understand than it adds in new files, interfaces, or indirection? An abstraction layer with one implementation and no real volatility fails the gate — drop it and say why. Treat SOLID, connascence, and Clean-Code rules as heuristics that a smell triggers, never as laws to apply top-down.

**Done when:** you have a prioritized list where each item names its smell, the principle behind it, the concrete fix, and the payoff — and every item has passed the gate.

### 4. Agree the plan

Explain the smallest useful fixes and their navigation impact. Use an **as-is → to-be** visual when structural changes are difficult to assess in prose or the user requests one; see [VISUAL-DIFF.md](reference/VISUAL-DIFF.md).

Recommend the smallest high-leverage set rather than the whole list. Surface risk, and flag anything that contradicts an existing ADR (see [DOCS.md](reference/DOCS.md)) so the user can decide whether to reopen it. Proceed within the requested or confirmed scope. Ask before materially changing behavior, public contracts, or an unresolved architectural decision.

**Done when:** the chosen fixes and risks are clear and covered by the user’s existing authorization or a necessary scope decision.

### 5. Pin behavior with tests

Refactoring rests on tests that fail if behavior changes. For any area you will touch that lacks such a test, add a **characterization test** first — one that pins what the code *actually* does now, not what it should do. Inject fakes only at real boundaries (clock, network, filesystem, DB) and mask non-deterministic output (timestamps, random IDs, ordering). The how-to, and the rule this rests on, are in [SAFE-REFACTOR.md](reference/SAFE-REFACTOR.md).

**Done when:** every area the plan will touch is covered by a green test that would fail if its behavior changed.

### 6. Apply surgically — one hat, small steps

Wear the **refactoring hat**: change structure, not behavior. Apply one named move at a time from [SAFE-REFACTOR.md](reference/SAFE-REFACTOR.md) — deepen a shallow module, replace a nested conditional with **guard clauses**, introduce a parameter object or value object, rename a concept across every occurrence, inline a pass-through wrapper. Run focused checks after each coherent batch. If a new failure appears, inspect the latest change and correct or revert it without discarding unrelated work.

Match the surrounding style. Touch only what the goal requires. Preserve existing **why-comments**. Any intended behavior change waits for a separate, test-first commit under the adding-function hat.

**Done when:** every chosen fix is applied, the relevant checks pass after each batch, and the diff is scoped to the target with unrelated code untouched.

### 7. Make it navigable — names, docs, structure

Close the loop for the next reader, human or agent:

- **Names** — domain nouns and verbs map to first-class symbols (a `processRefund` method, a `Refund` type), one naming convention repo-wide; a rename fixes *every* occurrence.
- **Docs** — add a concise purpose header or docstring (the *why* and the contract) wherever a signature does not speak for itself. Update every doc the change touched *in the same diff* — README snippet, docstring, reference, ADR pointer — keeping one source of truth with no contradictions, and verify any install or usage command still runs. [DOCS.md](reference/DOCS.md) decides which doc type and how much.
- **Structure** — where it helped the goal, related code is colocated and hidden coupling is gone, so local reasoning is enough for a correct change.

**Done when:** every renamed concept is updated at all occurrences; every doc the change touched is updated in the same diff with its commands verified to run; and no contradictory source of truth remains.

### 8. Verify and record

Run the repository-required tests and checks relevant to the target; reuse current results for unchanged state. Report precisely what ran and what passed — quote the evidence; do not claim success without it. Then record the decision where the repo already keeps a trail — a changelog entry, an ADR, or the PR description — capturing the smell you fixed and the alternative you rejected and why.

**Done when:** the named checks are green with quoted evidence, and the decision is recorded.

