agentsclimarketplace

Clean code

Skill patforna/core-skills/skills/clean-code

Reusable, project-agnostic engineering and multi-model skills for Claude Code

Install
npx -y skills add patforna/core-skills --skill clean-code

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 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

Clean code review lens (Martin-style). Use when reviewing code for readability, naming, function design, error handling, and code smells. TRIGGER when: reviewing code quality, doing code review, repo health check, or user asks about clean code principles. DO NOT TRIGGER when: user is focused on domain modelling (use /core-skills:ddd) or test-driving new code (use /core-skills:tdd).

SKILL.md

15.2 KB, as published. Nobody here has run it

Clean Code — Review Lens

You are reviewing code through the Clean Code lens. Scan for the smells and violations below. When you find one, name the specific smell (e.g., "G14: Feature Envy") and state the fix.

Naming

When reviewing names, apply these rules in order:

When you see...Flag as...Fix
Name requires reading the implementation to understandN1: Non-descriptive nameRename to reveal intent
Two names differ only in spelling (XYZController / XYZManager)Meaningless distinctionPick one term per concept, use it consistently
Name communicates implementation (phoneNumber on an abstract interface)N2: Wrong abstraction levelRename to the concept (connectionLocator)
Name doesn't use domain/pattern vocabulary when it couldN3: Non-standard nomenclatureUse pattern name (Decorator, Factory) or domain term
Name is ambiguous about what the function actually doesN4: Ambiguous nameRename to include the full scope of behavior
Short name in a large scope, or long name in a tiny scopeN5: Scope-length mismatchi fine in 3-line loop; module-level names should be descriptive
Hungarian notation, m_ prefix, I prefix on interfacesN6: Encoding in nameRemove the encoding; modern tooling makes it redundant
Name hides a side effect (getX() that also creates X)N7: Hidden side effectRename to describe all effects (createOrReturnX)
Same word used for two different operations (e.g., add for both append and insert)PunUse distinct words for distinct operations

Functions

When you see...Flag as...Fix
Function body has sections at different abstraction levelsG34: Mixed abstractionExtract lower-level operations into named helper functions
Function does more than one thing (you can extract a meaningfully-named function from it)G30: Does too muchExtract until each function does one thing
Function takes a boolean argument that selects behaviorF3/G15: Flag/selector argSplit into two functions, one per branch
Function has 3+ parametersF1: Too many argumentsWrap related args into an object, or restructure
Function modifies an argument instead of returning a valueF2: Output argumentHave the owning object perform the mutation via method call
Function both changes state AND returns a valueCommand-query violationSplit: one function to change state, another to query it
Function body is a try/catch with logic inside both blocksUnseparated error handlingExtract try body and catch body into named functions
Function is never calledF4: Dead functionDelete it; VCS remembers
if/else or switch dispatches on type in multiple placesG23: Missing polymorphismReplace with polymorphic objects; at most one switch to create them

Comments

When you see...Flag as...Fix
Comment restates what the code already saysC3: Redundant commentDelete it
Comment contradicts the codeC2: Obsolete commentUpdate or delete it
Comment contains change history, author, dateC1: Inappropriate infoRemove; this belongs in version control
Commented-out codeC5: Commented-out codeDelete it; VCS remembers
Comment is vague, rambling, or ungrammaticalC4: Poorly writtenRewrite clearly and concisely, or delete if unnecessary
Doc-comment boilerplate that adds nothing beyond the signatureNoiseDelete it; only write comments that say what code cannot

Good comments to preserve: legal notices, explanation of intent behind a non-obvious decision, clarification of an obscure API call, warning of consequences, TODO with ticket reference, amplification of something easily overlooked.

Error Handling

When you see...Flag as...Fix
Error signalled by return code or special value (e.g., -1, null)Return-code error styleUse exceptions to separate happy path from error path
Null returned from a functionNull returnReturn empty collection, Optional, or a Special Case object
Null passed as a function argumentNull argumentForbid by convention; fail fast with clear error if received
Catch block is empty or logs and continuesSwallowed exceptionHandle it, re-raise with context, or propagate
Exception message lacks context about what failedContext-free exceptionInclude the operation attempted and the failure reason
Third-party API exceptions leak through the codebaseUnwrapped boundaryWrap third-party calls; translate their exceptions into your domain exceptions
Code checks for a special condition and returns null/throwsMissing Special CaseCreate a Special Case object that encapsulates the default behavior

Structure and Coupling

When you see...Flag as...Fix
Method chains: a.getB().getC().doSomething()G36: Transitive navigation (Law of Demeter)a.doSomething() — ask the immediate collaborator
Method mostly uses another object's getters to do workG14: Feature EnvyMove the method to the class whose data it uses
Class has multiple unrelated reasons to changeSRP violationSplit into focused classes, one responsibility each
Class has low cohesion (methods use different subsets of instance variables)Low cohesionSplit into multiple classes, each highly cohesive
Constants/functions placed in a convenient but wrong moduleG13: Artificial couplingMove to the module where they logically belong
Base class references or imports its own derived classesG7: Base depends on derivativesInvert the dependency; base should not know about derivatives
Implementation details in an abstract interfaceG6: Wrong abstraction levelPush implementation details down to derived classes/modules
Two functions must be called in a specific order, but nothing enforces itG31: Hidden temporal couplingUse bucket brigade: each function returns what the next needs
Data or constants that could change are buried in low-level codeG35: Configuration at wrong levelMove configurable values to high-level initialization
A dependency exists logically but is not explicit in the codeG22: Logical dependency not physicalMake the dependency explicit via parameter or interface
Class/module exposes too many methods, variables, or constantsG8: Too much informationMinimize the public interface; hide data, utilities, constants
Static method that could plausibly need polymorphic dispatchG18: Inappropriate staticMake it an instance method; only use static when polymorphism is impossible

Duplication and Dead Code

When you see...Flag as...Fix
Identical or near-identical code in multiple placesG5: DuplicationExtract into a shared function or class
Repeated if/else or switch chains testing the same conditionsG5: Structural duplicationReplace with polymorphism or Template Method
Modules with similar algorithms but different detailsG5: Algorithmic duplicationExtract common structure using Template Method or Strategy
Code in an if that can never be true, catch that can never fireG9: Dead codeDelete it
Unused variables, unused imports, empty default constructorsG12: ClutterDelete them

Formatting and Clarity

When you see...Flag as...Fix
Public function at bottom, private helpers at topInverted newspaper orderPut high-level public functions first, helpers below them
Variable declared far from where it is usedG10: Vertical separationMove declaration close to first usage
No blank lines between distinct concepts in a functionMissing vertical opennessAdd blank lines to separate logical sections
Related functions scattered across the fileConceptual disaffinityGroup related functions together; caller above callee
Magic number or magic string literalG25: Magic numberExtract to a named constant
Complex boolean expression inline in ifG28: Unencapsulated conditionalExtract to a well-named predicate function
Negative conditional (if (!isNotFound()))G29: Negative conditionalRewrite as positive (if (isFound()))
Dense expression with unclear intentG16: Obscured intentBreak into explanatory variables (G19) with meaningful names
Boundary arithmetic (level + 1) repeated in multiple placesG33: Unencapsulated boundaryExtract to a named variable (nextLevel = level + 1)
Similar operations use inconsistent patterns or namingG11: InconsistencyAdopt one convention and apply it uniformly

Boundaries

When reviewing code that uses third-party libraries or APIs:

  1. Wrap, don't leak: Third-party types should not spread through the codebase. Wrap the third-party API in your own class that exposes only what you need.
  2. Learning tests: If the codebase uses a third-party API, check for tests that document expected behavior of that API. Recommend adding them if missing.
  3. Adapter at the boundary: When your code needs an interface that doesn't exist yet (e.g., from an external team), define the interface you want, then write an adapter when the real API arrives.

Review Checklist

After scanning for individual smells, check these cross-cutting concerns:

  • Obvious behavior implemented? (G2) — Does every function/class do what its name promises?
  • Boundary conditions tested? (G3) — Are edge cases handled, not just the happy path?
  • No overridden safeties? (G4) — Are warnings enabled, tests running, type checks in place?
  • Precise? (G26) — Are types correct (no float for currency), concurrency handled, null cases addressed?
  • Algorithm understood? (G21) — Is the code obviously correct, not just "passes the tests I thought of"?
  • Structure enforces design? (G27) — Are constraints enforced by the type system or architecture, not just naming conventions?
  • Don't be arbitrary (G32) — Does every structural choice have a reason? Would a new contributor understand why?

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.