smell

Detect software architecture bad smells, algorithmic complexity hotspots, and anti-patterns in a codebase. Produces a detailed markdown report identifying violations of architectural principles, design patterns, code quality, and performance complexity. Triggers on: smell, code smell, architecture s

By smallnest · 492 installs

npx skills add smallnest/goal-workflow --skill smell

Source repository · Upstream listing

Smell — Architecture Bad Smell Detector Analyze a codebase to find violations of software architecture principles, anti patterns, code "bad smells," and algorithmic complexity hotspots. Produce a comprehensive, actionable markdown report. Knowledge base: This skill encodes architectural patterns, anti patterns, code smells, and algorithmic complexity heuristics drawn from industry research and practice, including the classic code smells catalog by Martin Fowler / Kent Beck (as organized on refactoring.guru: Bloaters, Object Orientation Abusers, Change Preventers, Dispensables, Couplers). The Job 1. Understand the scope — ask what part of the project to analyze (full project, specific module, or recent changes) 2. Scan the codebase using find , grep , and Agent (Explore subagent) to gather candidate signals and evidence 3. Validate candidates against context, callers, history, workload, and measurements before confirming findings 4. Generate a detailed markdown report saved to tasks/smell report [timestamp].md 5. Present a summary of confirmed findings and separate candidates to the user Step 1: Scope Clarification Ask the user: If the user doesn't specify, default to option A for small projects (< 100 files) or C for large projects. Step 2: Evidence Gathering Use the Explore subagent ( Agent with subagent type: "Explore" ) to scan the codebase for architectural patterns and anti patterns. Run multiple parallel explorations: Exploration Commands Run these in parallel to gather evidence efficiently: 1. Project Structure Scan: Map the directory tree, identify the architectural style (layered, modular monolith, microservices, etc.) 2. Dependency Analysis: Find import/include patterns, check for circular dependencies, identify coupling hotspots 3. Module/Component Scan: Identify God Objects (files 500 lines), check cohesion, check single responsibility violations 4. Pattern Detection: Look for known anti pattern signatures (static cling, service locator abuse, leaky abstractions) 5. Testing Scan: Check test coverage patterns, test file locations, test to code ratios 6. Naming & Clarity Scan: Flag misleading names, overly generic names (Manager, Helper, Util), inconsistent naming conventions 7. Complexity Scan: Detect algorithmic complexity hotspots — nested loops, N+1 queries, repeated scans, sort in loop, expensive recomputation in render paths Key Heuristics Heuristics are candidate signals, not findings . A line count, nesting, naming, or Big O match must be validated against the code's responsibility, callers, change history, workload, and intentional constraints. Do not assign severity from a threshold alone. Category Smell Detection Heuristic Architecture Big Ball of Mud No clear directory structure; everything in root or one flat folder; no separation of concerns Architecture Violated Layer Boundaries Inner layers importing outer layers; infrastructure code in domain/core layer Architecture Missing Architecture No src/ , lib/ , core/ separation; SQL inline with UI code; HTTP handlers mixed with business logic Architecture Distributed Monolith Microservices sharing a database; services that can't deploy independently Architecture Anemic Domain Model Model/entity classes with only getters/setters and no behavior; all logic in services Architecture CQRS Without Need Separate read/write models for simple CRUD; unnecessary complexity Architecture Over Layered Architecture Excessive layers/tiers that add pass through code with no real value Architecture Over Abstraction So many indirections/interfaces/generics that you get lost following the code Architecture Futuristic Architecture Speculative flexibility for requirements that may never come (predicting the future) Architecture Technology Enthusiast Architecture Shiny/unproven tech adopted in production because it's new, not because it fits Architecture Overkill Architecture Heavyweight architecture/tech thrown at a simple problem Architecture Cloud/Visio Architecture Diagrams disconnected from the actual code and runtime reality Coupling Circular Dependencies Module A imports B, B imports A; detected via import graph analysis Coupling Content Coupling One module directly accesses another's internal/private members Coupling Common Coupling Excessive global variables/shared mutable state; singleton abuse Coupling Stamp Coupling Passing large data structures when only a few fields are needed Cohesion God Object Single class/module 500 lines; 20 public methods; handles unrelated concerns Cohesion Shotgun Surgery A single change requires touching 5+ files across unrelated modules Cohesion Feature Envy Method calls foreign class methods more than its own class methods Cohesion Data Clumps Same group of 3+ parameters appearing together in multiple method signatures Design Leaky Abstractions Implementation details (DB queries, HTTP calls) exposed through interfaces Design Static Cling Excessive use of static methods; static state that prevents testability Design Service Locator Abuse DI container passed around instead of proper constructor injection Design Violated SOLID SRP violations, OCP violations (switch/if else chains on types), ISP violations (fat interfaces) Design Switch Statements Same switch /if else chain on a type code appearing in multiple places; should be polymorphism Design Refused Bequest Subclass inherits methods/fields it doesn't use or overrides them to throw/no op Design Alternative Classes w/ Different Interfaces Two classes do the same thing but have differently named methods Design Parallel Inheritance Hierarchies Creating a subclass in one hierarchy forces a matching subclass in another Design Speculative Generality Unused abstract classes, hooks, params, or generics "for future needs" (YAGNI) Design Incomplete Library Class Wrapping/patching a third party class because it lacks needed methods Cohesion Divergent Change One module changed for many unrelated reasons (opposite of Shotgun Surgery) Cohesion Data Class Class with only fields + getters/setters, no behavior (anemic data bag) Cohesion Lazy Class Class/module that does too little to justify its existence Coupling Inappropriate Intimacy Two classes access each other's private/internal parts too much Coupling Message Chains Long call chains a.getB().getC().getD() (Law of Demeter violation) Coupling Middle Man Class that only delegates every call to another class Code Temporary Field Instance field set/used only in certain circumstances, empty otherwise Code Duplicated Code Identical/similar logic appearing in 3+ places; copy paste patterns Code Long Method Methods 50 lines; deep nesting ( 3 levels) Code Long Parameter List Methods with 4 parameters Code Primitive Obsession Using strings/ints instead of domain types (e.g., string email instead of Email type) Code Magic Numbers/Strings Hardcoded literals without named constants Code Comments as Deodorant Excessive comments explaining bad code instead of refactoring Code Dead Code Unused imports, unreachable code, commented out blocks Testing No Tests Modules with zero test coverage Testing Test Implementation Coupling Tests that assert internal implementation details instead of behavior Testing Slow Tests Tests doing real I/O, database calls, network requests without mocking Naming Vague Names Manager , Handler , Processor , Helper , Util , Service , Data , Info used excessively without context Naming Inconsistent Naming Snake case and camelCase mixed; different patterns for same concept Readability Deep Nesting (Arrow Anti Pattern) Loops/conditionals nested 3 levels deep; rightward drifting "arrow" shape hard to trace Complexity Nested Loops (O(n^2)+) Loop inside loop; forEach inside for; map inside map; nested iteration suggesting polynomial complexity Complexity Repeated Linear Scan includes() / indexOf() / .find() inside a loop; O(n m) membership check on list instead of Set/Map Complexity Sort in Loop .sort() or sorted() called inside iterative code; repeated O(n log n) when sort once suffices Complexity N+1 Query Pattern Database/API/HTTP call inside a loop; fetch / query / execute / findMany per iteration instead of batch Complexity Render Path Recompute .filter().map().sort() chains in component render body; expensive transforms without memoization Complexity Pairwise Comparison Nested iteration comparing every element with every other; O(n^2) when sort+two pointer would be O(n log n) Complexity Unnecessary Recompute Same expensive computation repeated without caching; missing useMemo / memo /lazy eval Complexity Wrong Data Structure Array used where Set/Map would give O(1) lookup; List where Queue/Heap/Stack is natural fit Step 3: Report Generation Finding Identity and Evidence Process every candidate in three stages: 1. Candidate detection: static patterns, file metrics, and dependency scans produce candidates only. 2. Context validation: read the implementation and relevant callers; check change frequency, input size, runtime frequency, framework constraints, generated/vendor status, and existing mitigations. 3. Finding confirmation: merge candidates with the same root cause, affected path, failure/change scenario, and remediation direction into one finding. Count findings by independent root cause, never by the number of principles they implicate. Use one Primary principle and optional Related principles . SOLID is an umbrella label; use SRP , OCP , or DIP as the primary label when the evidence supports a specific lens, without also creating a separate SOLID finding. Canonical 11 Principle Matrix Principle Confirming evidence Common false positive / constraint SOLID A design problem spans multiple SOLID lenses or no narrower lens is reliable Do not duplicate a specific SRP/OCP/DIP finding DRY The same business rule or knowledge must change in multiple places Similar syntax that is expected to evolve independently KISS Extra layers, indirection, or machinery add cost without observable leverage A small abstraction that removes real complexity YAGNI Unused extension points, parameters, adapters, or speculative requirements A tested seam required by an existing boundary or change SRP Multiple independent reasons to change, supported by responsibilities or change history File size or method count alone Open/Closed (OCP) Adding a known variant repeatedly modifies stable branching logic One simple, local conditional Dependency Inversion (DIP) High level policy directly depends on concrete infrastructure, harming replacement or testing Adding an interface for a single stable implementation Composition Inheritance causes unwanted coupling, refused behavior, or inseparable variation axes Replacing every valid inheritance relationship mechanically Separation of Concerns Business policy, I/O, presentation, or persistence concerns leak across boundaries A deliberately thin boundary adapter Fail Fast Invalid input, state, or dependency propagates until a distant operation fails Intentional aggregation, retry, or deferred validation semantics Measure First A performance, scale, or optimization claim lacks a baseline or representative workload Static complexity reported