Audit complexity
Agent skills for agentic coding tools. Extremely opinionated. Updated (almost) daily.
npx -y skills add JHostalek/dotclaude --skill audit-complexityAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 10 stars10 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use when the goal is to reduce code size, remove unnecessary complexity, or simplify a module without removing user-facing behavior.
SKILL.md
3.8 KB, as published. Nobody here has run it
!cat "${CLAUDE_SKILL_DIR}/../audit-workflow.md"
Run as the complexity dimension. Exists because LOC and abstraction count compound silently — each addition seems reasonable; the total becomes unnavigable. Lens:
Maximize net LOC reduction while readability holds or improves. Metric: git diff --stat delta. Hard constraint: behavior-preservation. Default = DELETE — every line justifies itself or goes. Auto-fix = anything behavior-preserving: file merges, abstraction collapses, internal API changes, test rewrites. Sign-off required only for user-facing capability removal (endpoints, tools, CLI commands, features) where usage can't be verified.
Pretraining biases toward keeping abstractions: ABCs, factories, service layers, config objects read as "professional." Wrong here — most abstractions in real code serve exactly one call site. Professional = minimal; ceremony = amateur. Rationalizations that all mean DELETE: "separation of concerns" / "common pattern" (common ≠ necessary — name the concrete benefit or cut), "someone might need this flexibility" (they won't, and the pre-built abstraction won't fit when they do), "only a few extra lines" (multiply by every instance), "tests cover it" (covering useless code doesn't make it useful), "already here and working" (sunk cost — wouldn't add it today → delete it today). Expect ≥15% removal from a genuinely bloated file; less signals early stopping.
Distillation depth, in typical yield order:
- Dead code (usually 50%+ of savings). Grep the whole codebase for callers — exports, tests, dynamic references — not just the module. Zero callers + zero coverage → delete, not comment out, not TODO. Caution: dynamically-discovered symbols are live with no static callers — Django models, Flask/decorator registries, React lazy imports, CLI command registries, plugin entry points.
- Premature generalization. Count concrete implementations. One → abstraction is dead weight. ABC/Protocol w/ one class → delete ABC. Factory building one type → inline. Service class of static methods → module fns. Pass-through wrapper → inline. Single-use util → inline.
- Duplication. Extract only at 4+ lines, 2+ occurrences, ≤2 params. Don't mint new abstractions while killing old ones.
- Defensive bloat. Exception re-wrap w/o added context. Null checks after non-nullable sources. Validation the framework already does (Pydantic/Zod/serde). Try/catch that logs and re-raises unchanged. Defensive copies nobody mutates.
- Surface compression (low yield, high count). Stale
# noqa:, single-use intermediates, in-place-obvious constants, multi-line literals that fit on fewer lines. - Structural (cross-file). File merges — single-function files into their consumer; thin
types.py/schemas.py/exceptions.pyinto adjacent modules; any non-__init__.pyfile under ~30 lines: question whether it should exist. Abstraction collapse across modules. Heavy library where stdlib suffices; stateful class where a function would do. Config knobs set to the same value in every environment. Grep every reference and fix all imports in one pass. - Test infra heavier than the code under test. Cutting the tests themselves is
audit-tests; you own the scaffolding around them.
Never cut: logging lines, type annotations, user-facing schema descriptions, error messages carrying domain context, tests encoding business rules or integration contracts, framework-registered symbols (decorators, route handlers, model classes). ~3+ lines saved required to justify any readability cost. No fighting the formatter; no breaking encapsulation for LOC.