skills/simplifying-code/SKILL.md
Simplifies, polishes, and declutters code without changing behavior. Use when asked to simplify, clean up, refactor, declutter, remove dead code or AI slop, or improve readability. For analysis-only reports without code changes, use code-simplicity-reviewer agent.
npx skillsauth add iliaal/ai-skills simplifying-codeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Principle | Rule | |-----------|------| | Preserve behavior | Output must do exactly what the input did -- no silent feature additions or removals. Specifically preserve: async/sync boundaries (do not convert sync to async or reverse), error propagation paths (do not alter strategy), logging/telemetry/guards/retries that encode operational intent, and domain-specific steps (do not collapse into generic helpers that hide intent) | | Explicit over clever | Prefer explicit variables over nested expressions. Readable beats compact | | Simplicity over cleanliness | Prefer straightforward code over pattern-heavy "clean" code. Three similar lines beat a premature abstraction | | Surgical changes | Touch only what needs simplifying. Match existing style, naming conventions, and formatting of the surrounding code | | Surface assumptions | Before changing a block, identify what imports it, what it imports, and what tests cover it. Edit dependents in the same pass |
git blame before removing it. First understand the reason, then decide if the reason still applies.ia-verification-before-completion's Scope Confirmation gate.| Smell | Fix |
|-------|-----|
| Deep nesting (>2 levels) | Guard clauses with early returns |
| Long function (>20 lines) | Extract into named functions by responsibility |
| Too many parameters (>3) | Group into an options/config object |
| Duplicated block (3+ occurrences) | Extract shared function. Two copies = leave inline; wait for the third |
| Magic numbers/strings | Named constants |
| Complex conditional | Extract to descriptively-named boolean or function |
| Boolean-returning if/else (each branch returns a literal True/False) | Collapse to the boolean expression itself: return a and b, not a branch per literal |
| Dense transform chain (3+ chained methods) | Break into named intermediates for debuggability |
| Dead code / unreachable branches | Delete entirely -- no commented-out code |
| Unnecessary else after return | Remove else, dedent |
When simplifying AI-generated code, specifically target:
// increment counter above counter++) -- delete themas any, as unknown as T) -- fix the actual type or use a proper generic// ..., // rest of code, // similar to above, // continue pattern, // add more as needed) -- leave unsimplified code as-is rather than replacing it with stubscatch(e) { throw e; }, catch(e) { throw new Error(e.message); }) that strips the original stack for no reason -- remove the try/catch entirely and let errors propagatearray_filter, Array.from, Collection::pluck(), itertools) -- replace with the stdlib/framework one-liner, but verify edge-case parity first: empty input, null/None guard, no-match default, zero-value path. The one-liner can silently differ from the loop (an empty-input crash, a missing no-match default, lost ordering) -- a structurally cleaner version that changes behavior on an edge case is not a simplificationStop and ask before proceeding when:
When this skill is invoked by an orchestrator that also runs ia-code-review, ia-writing-tests, or ia-verification-before-completion on the same scope, each sub-skill re-resolving scope independently wastes tokens and risks drift. Avoid this by resolving scope exactly once and passing a canonical block to every sub-skill.
Resolved scope format — the orchestrator builds this once, before dispatching any sub-skill:
## Resolved scope
Files:
- path/to/file-a.ts
- path/to/file-b.ts
Commit range: HEAD~3..HEAD (or "uncommitted")
Intent: [one-sentence description pulled from the user request or PR description]
Constraints:
- Preserve public API
- No behavior change
- [other constraints specific to this run]
Every chained sub-skill receives this block verbatim in its prompt and uses it as the source of truth — no re-running git diff --name-only, no re-parsing the user request, no independent scope resolution. Sub-skills accept --no-verify --no-report flags when chained so verification and reporting happen once at the end of the chain, not per-skill. The last sub-skill in the chain runs verification; the orchestrator trusts that result rather than re-verifying.
This prevents two failure modes: scope drift (sub-skill A simplifies one set of files, sub-skill B reviews a different set) and double work (every sub-skill rediscovers the same facts).
ia-code-simplicity-reviewer agent -- analysis-only pass producing a simplification report (no code changes). Use before refactoring to identify targets.After simplifying, report:
development
Generic test writing discipline: test quality, real assertions, anti-patterns, and rationalization resistance. Use when writing tests, adding test coverage, or fixing failing tests for any language or framework. Complements language-specific skills.
testing
Enforces fresh verification evidence before any completion claim. Use when about to claim "tests pass", "bug fixed", "done", "ready to merge", or handing off work.
tools
Tailwind CSS v4 patterns: CSS-first config, utility classes, component variants, v3 migration. Use when styling with Tailwind, configuring @theme tokens, using tailwind-variants/CVA, migrating v3 to v4, or fixing Tailwind styles and dark mode.
tools
Rust patterns for CLI tools, backend services, and general application code. Use when working with Rust, Cargo workspaces, axum/tokio services, clap CLIs, async concurrency, or configuring clippy, rustfmt, cargo-nextest, or Cargo.toml.