Source profileQuality 95/100

smallnest/goal-workflow/skills/smell/SKILL.md

smell

Use it for testing and engineering tasks; the detail page covers purpose, installation, and practical steps.

Source repository stars
237
Declared platforms
0
Static risk flags
2
Last source update
2026-08-16
Source checked
2026-08-25

Decision brief

What it does: where it fits

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.

Best for

    Not for

    • Architectural Anti-Patterns
    • Big Ball of Mud

    Compatibility matrix

    Platform support, with evidence labels

    PlatformStatusEvidenceWhat to check
    CodexNot declaredNo explicit evidencePortability before use
    Claude CodeNot declaredNo explicit evidencePortability before use
    CursorNot declaredNo explicit evidencePortability before use
    Gemini CLINot declaredNo explicit evidencePortability before use
    Open the compatibility checker

    Installation

    Inspect first. Install second.

    The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.

    Source-detected install commandSource
    npx skills add https://github.com/smallnest/goal-workflow --skill "skills/smell"
    Safe inspection promptEditorial

    Inspect the Agent Skill "smell" from https://github.com/smallnest/goal-workflow/blob/f7bb561169ec4fcde0d2769d01eb53010bb05cc8/skills/smell/SKILL.md at commit f7bb561169ec4fcde0d2769d01eb53010bb05cc8. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.

    Workflow

    What the source asks the agent to do

    1. 01

      Step 1: Scope Clarification

      If the user doesn't specify, default to option A for small projects (< 100 files) or C for large projects.

      If the user doesn't specify, default to option A for small projects (< 100 files) or C for large projects.
    2. 02

      Step 2: Evidence Gathering

      Use the Explore subagent (Agent with subagenttype: "Explore") to scan the codebase for architectural patterns and anti-patterns. Run multiple parallel explorations:

      Project Structure Scan: Map the directory tree, identify the architectural style (layered, modular monolith, microservices, etc.)Dependency Analysis: Find import/include patterns, check for circular dependencies, identify coupling hotspotsModule/Component Scan: Identify God Objects (files 500 lines), check cohesion, check single responsibility violations
    3. 03

      Step 3: Report Generation

      Process every candidate in three stages:

      Candidate detection: static patterns, file metrics, and dependency scans produce candidates only.Context validation: read the implementation and relevant callers; check change frequency, input size, runtime frequency, framework constraints, generated/vendor status, and existing mitigations.Finding confirmation: merge candidates with the same root cause, affected path, failure/change scenario, and remediation direction into one finding.
    4. 04

      Step 4: Save and Present

      Save the report to tasks/smell-report-[YYYY-MM-DD-HHmm].md and present a brief summary to the user.

      Save the report to tasks/smell-report-[YYYY-MM-DD-HHmm].md and present a brief summary to the user.
    5. 05

      Test-Implementation Coupling

      Tests asserting internal method calls, private state, or implementation details

      Tests asserting internal method calls, private state, or implementation detailsTests breaking on refactoring without behavior changesRemedy: Test through public APIs, assert behavior not implementation

    Permission review

    Static risk signals and limitations

    Reads files

    low · line 12

    The documentation asks the agent to read local files, directories, or repositories.

    Scan the codebase using `find`, `grep`, and `Agent` (Explore subagent) to gather candidate signals and evidence

    Reads files

    low · line 37

    The documentation asks the agent to read local files, directories, or repositories.

    *Use the Explore subagent** (`Agent` with `subagent_type: "Explore"`) to scan the codebase for architectural patterns and anti-patterns. Run multiple parallel explorations:

    Network access

    medium · line 110

    The documentation includes network, browsing, or remote request actions.

    | **Complexity** | N+1 Query Pattern | Database/API/HTTP call inside a loop; `fetch`/`query`/`execute`/`findMany` per iteration instead of batch |

    Network access

    medium · line 580

    The documentation includes network, browsing, or remote request actions.

    A database query, API call, or I/O operation inside a loop body.

    Evidence record

    Why each signal appears

    EvidenceSourceComputedTestedEditorial
    SignalValueEvidence typeMeaning
    Quality score95/100ComputedDocumentation, specificity, maintenance, and trust rules
    Repository stars237SourceRepository attention, not individual Skill quality
    Compatibility0 platformsSourceDeclared in the catalog source record
    Usage guideautomated source guideEditorialGenerated or reviewed according to the visible evidence level

    Pinned source

    Provenance and original SKILL.md

    Repository
    smallnest/goal-workflow
    Skill path
    skills/smell/SKILL.md
    Commit
    f7bb561169ec4fcde0d2769d01eb53010bb05cc8
    License
    MIT
    Collected
    2026-08-25
    Default branch
    master
    View the original SKILL.md

    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:

    What scope should I analyze?
      A. Entire project (thorough, may take time)
      B. Specific module/directory: [please specify]
      C. Only recently changed files (git diff)
      D. Only architectural-level issues (skip low-level code smells)
    

    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.

    CategorySmellDetection Heuristic
    ArchitectureBig Ball of MudNo clear directory structure; everything in root or one flat folder; no separation of concerns
    ArchitectureViolated Layer BoundariesInner layers importing outer layers; infrastructure code in domain/core layer
    ArchitectureMissing ArchitectureNo src/, lib/, core/ separation; SQL inline with UI code; HTTP handlers mixed with business logic
    ArchitectureDistributed MonolithMicroservices sharing a database; services that can't deploy independently
    ArchitectureAnemic Domain ModelModel/entity classes with only getters/setters and no behavior; all logic in services
    ArchitectureCQRS Without NeedSeparate read/write models for simple CRUD; unnecessary complexity
    ArchitectureOver-Layered ArchitectureExcessive layers/tiers that add pass-through code with no real value
    ArchitectureOver-AbstractionSo many indirections/interfaces/generics that you get lost following the code
    ArchitectureFuturistic ArchitectureSpeculative flexibility for requirements that may never come (predicting the future)
    ArchitectureTechnology-Enthusiast ArchitectureShiny/unproven tech adopted in production because it's new, not because it fits
    ArchitectureOverkill ArchitectureHeavyweight architecture/tech thrown at a simple problem
    ArchitectureCloud/Visio ArchitectureDiagrams disconnected from the actual code and runtime reality
    CouplingCircular DependenciesModule A imports B, B imports A; detected via import graph analysis
    CouplingContent CouplingOne module directly accesses another's internal/private members
    CouplingCommon CouplingExcessive global variables/shared mutable state; singleton abuse
    CouplingStamp CouplingPassing large data structures when only a few fields are needed
    CohesionGod ObjectSingle class/module > 500 lines; > 20 public methods; handles unrelated concerns
    CohesionShotgun SurgeryA single change requires touching 5+ files across unrelated modules
    CohesionFeature EnvyMethod calls foreign class methods more than its own class methods
    CohesionData ClumpsSame group of 3+ parameters appearing together in multiple method signatures
    DesignLeaky AbstractionsImplementation details (DB queries, HTTP calls) exposed through interfaces
    DesignStatic ClingExcessive use of static methods; static state that prevents testability
    DesignService Locator AbuseDI container passed around instead of proper constructor injection
    DesignViolated SOLIDSRP violations, OCP violations (switch/if-else chains on types), ISP violations (fat interfaces)
    DesignSwitch StatementsSame switch/if-else chain on a type code appearing in multiple places; should be polymorphism
    DesignRefused BequestSubclass inherits methods/fields it doesn't use or overrides them to throw/no-op
    DesignAlternative Classes w/ Different InterfacesTwo classes do the same thing but have differently-named methods
    DesignParallel Inheritance HierarchiesCreating a subclass in one hierarchy forces a matching subclass in another
    DesignSpeculative GeneralityUnused abstract classes, hooks, params, or generics "for future needs" (YAGNI)
    DesignIncomplete Library ClassWrapping/patching a third-party class because it lacks needed methods
    CohesionDivergent ChangeOne module changed for many unrelated reasons (opposite of Shotgun Surgery)
    CohesionData ClassClass with only fields + getters/setters, no behavior (anemic data bag)
    CohesionLazy ClassClass/module that does too little to justify its existence
    CouplingInappropriate IntimacyTwo classes access each other's private/internal parts too much
    CouplingMessage ChainsLong call chains a.getB().getC().getD() (Law of Demeter violation)
    CouplingMiddle ManClass that only delegates every call to another class
    CodeTemporary FieldInstance field set/used only in certain circumstances, empty otherwise
    CodeDuplicated CodeIdentical/similar logic appearing in 3+ places; copy-paste patterns
    CodeLong MethodMethods > 50 lines; deep nesting (> 3 levels)
    CodeLong Parameter ListMethods with > 4 parameters
    CodePrimitive ObsessionUsing strings/ints instead of domain types (e.g., string email instead of Email type)
    CodeMagic Numbers/StringsHardcoded literals without named constants
    CodeComments as DeodorantExcessive comments explaining bad code instead of refactoring
    CodeDead CodeUnused imports, unreachable code, commented-out blocks
    TestingNo TestsModules with zero test coverage
    TestingTest-Implementation CouplingTests that assert internal implementation details instead of behavior
    TestingSlow TestsTests doing real I/O, database calls, network requests without mocking
    NamingVague NamesManager, Handler, Processor, Helper, Util, Service, Data, Info used excessively without context
    NamingInconsistent NamingSnake_case and camelCase mixed; different patterns for same concept
    ReadabilityDeep Nesting (Arrow Anti-Pattern)Loops/conditionals nested > 3 levels deep; rightward-drifting "arrow" shape hard to trace
    ComplexityNested Loops (O(n^2)+)Loop inside loop; forEach inside for; map inside map; nested iteration suggesting polynomial complexity
    ComplexityRepeated Linear Scanincludes()/indexOf()/.find() inside a loop; O(n*m) membership check on list instead of Set/Map
    ComplexitySort-in-Loop.sort() or sorted() called inside iterative code; repeated O(n log n) when sort-once suffices
    ComplexityN+1 Query PatternDatabase/API/HTTP call inside a loop; fetch/query/execute/findMany per iteration instead of batch
    ComplexityRender-Path Recompute.filter().map().sort() chains in component render body; expensive transforms without memoization
    ComplexityPairwise ComparisonNested iteration comparing every element with every other; O(n^2) when sort+two-pointer would be O(n log n)
    ComplexityUnnecessary RecomputeSame expensive computation repeated without caching; missing useMemo/memo/lazy eval
    ComplexityWrong Data StructureArray 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

    PrincipleConfirming evidenceCommon false positive / constraint
    SOLIDA design problem spans multiple SOLID lenses or no narrower lens is reliableDo not duplicate a specific SRP/OCP/DIP finding
    DRYThe same business rule or knowledge must change in multiple placesSimilar syntax that is expected to evolve independently
    KISSExtra layers, indirection, or machinery add cost without observable leverageA small abstraction that removes real complexity
    YAGNIUnused extension points, parameters, adapters, or speculative requirementsA tested seam required by an existing boundary or change
    SRPMultiple independent reasons to change, supported by responsibilities or change historyFile size or method count alone
    Open/Closed (OCP)Adding a known variant repeatedly modifies stable branching logicOne simple, local conditional
    Dependency Inversion (DIP)High-level policy directly depends on concrete infrastructure, harming replacement or testingAdding an interface for a single stable implementation
    CompositionInheritance causes unwanted coupling, refused behavior, or inseparable variation axesReplacing every valid inheritance relationship mechanically
    Separation of ConcernsBusiness policy, I/O, presentation, or persistence concerns leak across boundariesA deliberately thin boundary adapter
    Fail FastInvalid input, state, or dependency propagates until a distant operation failsIntentional aggregation, retry, or deferred validation semantics
    Measure FirstA performance, scale, or optimization claim lacks a baseline or representative workloadStatic complexity reported as a measured bottleneck

    For each confirmed finding, record evidence strength (Measured, Observed, or Inferred) separately from confidence (High, Medium, or Low/Candidate). Evidence strength does not imply severity.

    Severity Rubric

    • Critical: correctness, reliability, security, data consistency, or measured system-level impact; normally requires high confidence.
    • Warning: clear reach or repeated change/runtime cost with a concrete maintenance or runtime consequence.
    • Suggestion: local, low-frequency, or limited-impact improvement with evidence.
    • Candidate requiring measurement: static signal with unknown impact; exclude it from severity totals and put it in a separate report section.

    Generate the report in this structure:

    # Architecture Smell Report
    
    **Project:** [project-name]
    **Scope:** [scope description]
    **Date:** [date]
    **Analyzer:** smell skill (Ducc)
    
    ---
    
    ## Executive Summary
    
    [2-3 paragraph summary of confirmed findings only: architectural style detected, overall health assessment, and top 3-5 critical issues. Mention candidates separately.]
    
    ---
    
    ## Architectural Style Detected
    
    [Identify the architectural style: Layered, Modular Monolith, Microservices, Hexagonal, Clean Architecture, or Big Ball of Mud]
    
    ### Style Expectations vs. Reality
    
    | Expectation | Reality | Status |
    |-------------|---------|--------|
    | [e.g., Clear layer separation] | [what was found] | ✅/⚠️/🔴 |
    
    ---
    
    ## Findings by Category
    
    ### 🔴 Critical Issues (Must Fix)
    
    [Issues that fundamentally undermine architecture]
    
    ### 🟡 Warnings (Should Fix)
    
    [Issues that degrade maintainability but don't block function]
    
    ### 🔵 Suggestions (Nice to Fix)
    
    [Minor improvements that would increase quality]
    
    ### Candidates Requiring Measurement
    
    [Static candidates whose runtime impact, change frequency, or workload is not yet established. These do not count toward severity totals.]
    
    ---
    
    ## Detailed Findings
    
    ### Finding #1: [Title]
    
    - **Category:** [Architecture/Coupling/Cohesion/Design/Code/Testing/Naming/Complexity]
    - **Severity:** 🔴 Critical / 🟡 Warning / 🔵 Suggestion
    - **Anti-Pattern:** [Name of anti-pattern]
    - **Location:** [file:line references and relevant callers]
    - **Confidence:** [High/Medium]
    - **Evidence strength:** [Measured/Observed/Inferred]
    - **Failure or change scenario:** [Concrete scenario]
    - **Primary principle:** [Most specific principle]
    - **Related principles:** [Explanatory only; do not count separately]
    - **Description:** [What was found and why it's a problem]
    - **Evidence:** [Code, dependency, history, or measurement]
    - **Measured/observed impact:** [Reach, frequency, consequence, or baseline]
    - **Recommendation:** [Smallest justified refactoring]
    - **Verification:** [How to prove behavior and impact]
    
    ---
    
    ## Dependency Graph Analysis
    
    [Summary of module dependencies, circular dependencies found, coupling hotspots]
    
    ---
    
    ## Module Health Scorecard
    
    | Module | Lines | God Object Risk | Coupling | Cohesion | Test Coverage | Health |
    |--------|-------|----------------|----------|----------|---------------|--------|
    | [name] | [N] | [Low/Med/High] | [Low/Med/High] | [Low/Med/High] | [% or N/A] | 🟢/🟡/🔴 |
    
    ---
    
    ## Smell Distribution
    
    Count only deduplicated confirmed findings by their primary category. Related principles and candidates do not affect these totals.
    
    | Category | Count | Critical | Warning | Suggestion |
    |----------|-------|----------|---------|------------|
    | Architecture | [N] | [N] | [N] | [N] |
    | Coupling | [N] | [N] | [N] | [N] |
    | Cohesion | [N] | [N] | [N] | [N] |
    | Design | [N] | [N] | [N] | [N] |
    | Code | [N] | [N] | [N] | [N] |
    | Testing | [N] | [N] | [N] | [N] |
    | Naming | [N] | [N] | [N] | [N] |
    | Complexity | [N] | [N] | [N] | [N] |
    
    ---
    
    ## Refactoring Roadmap
    
    Order work by impact, confidence, dependency sequence, and verification cost—not by principle count or smell name. Put only high-confidence, verifiable findings in Immediate Actions; for candidates, recommend the next measurement instead of a rewrite.
    
    ### Immediate Actions (This Sprint)
    1. [Actionable fix 1]
    2. [Actionable fix 2]
    
    ### Short-Term (1-3 Months)
    1. [Structural improvement 1]
    2. [Structural improvement 2]
    
    ### Long-Term (3-12 Months)
    1. [Architectural transformation 1]
    2. [Architectural transformation 2]
    
    ---
    
    ## Appendix: Anti-Pattern Reference
    
    [A condensed reference of anti-patterns checked, with brief descriptions]
    

    Step 4: Save and Present

    Save the report to tasks/smell-report-[YYYY-MM-DD-HHmm].md and present a brief summary to the user.


    Anti-Pattern Knowledge Base

    This section documents the architectural anti-patterns and bad smells the skill knows about.

    Architectural Anti-Patterns

    Big Ball of Mud

    The most common de-facto architecture. A haphazardly structured, sprawling system with no perceivable architecture. Characterized by:

    • Promiscuous sharing of information between distant elements
    • Global or duplicated important state
    • Structure eroded beyond recognition or never defined
    • Repeated expedient repair ("duct tape and bailing wire")
    • Forces: Time pressure, cost, inexperience, complexity, change, scale
    • Remedy: Define architecture boundaries, refactor incrementally, apply SHEARING LAYERS, KEEP IT WORKING

    Distributed Monolith

    Microservices that must be deployed together. Symptoms:

    • Services share a database
    • Synchronous chains of service calls
    • Changes require coordinated deployments
    • Remedy: Decouple data stores, introduce async messaging, enforce bounded contexts

    Anemic Domain Model

    Domain objects with only getters/setters (data bags), all logic in services. Violates:

    • "Tell, Don't Ask" principle
    • Rich Domain Model pattern from DDD
    • Remedy: Move behavior into domain objects, use domain services only for cross-aggregate operations

    God Object

    A class that knows too much or does too much. Characteristics:

    • 500 lines or > 20 public methods

    • Handles unrelated concerns
    • Difficult to test in isolation
    • Single Responsibility Principle violation
    • Remedy: Extract cohesive groups of methods into dedicated classes

    Leaky Abstractions

    Abstractions that expose implementation details. Signs:

    • Interface methods named after implementation (e.g., SaveToPostgres, FetchFromRedis)
    • Consumers catching implementation-specific exceptions
    • Configuration details exposed through abstractions
    • Remedy: Design interfaces from the consumer's perspective, hide implementation details

    Static Cling

    Excessive use of static methods/state. Problems:

    • Untestable (can't mock static calls)
    • Hidden dependencies
    • Thread-safety issues with static state
    • Remedy: Use dependency injection, convert stateless statics to instance methods

    Service Locator Abuse

    Using a service locator instead of dependency injection. Issues:

    • Hidden dependencies (dependencies not visible in constructor)
    • Runtime errors instead of compile-time errors
    • Testing difficulty
    • Remedy: Use constructor injection, register dependencies at composition root

    Violated Layer Boundaries (Clean/Onion/Hexagonal Architecture)

    In layered architectures:

    • Clean Architecture: Outer layers (frameworks) leaking into inner layers (use cases, entities)
    • Onion Architecture: Infrastructure concerns in domain core
    • Hexagonal Architecture: Business logic coupled to specific adapters instead of ports
    • Remedy: Apply dependency inversion, define clear port interfaces

    CQRS Overuse

    Applying CQRS to simple CRUD. Signs:

    • Separate read/write models for trivial data access
    • Event sourcing when events don't add business value
    • Unnecessary complexity
    • Remedy: Use CQRS only when read/write models genuinely differ or have different scaling needs

    Vertical Slice Contamination

    In Vertical Slice Architecture:

    • Cross-slice coupling (one feature directly calling another)
    • Shared service classes undermining slice independence
    • Remedy: Use events/messages for cross-slice communication, duplicate simple logic if needed

    Top Ten Software Architecture Mistakes

    A set of architecture-level anti-patterns describing over- and under-engineering. The common thread: architecture disconnected from real needs and reality. The opposite extreme (too little architecture) is equally a smell.

    Over-Layered / Multitier Architecture

    "Layers on layers on layers." Adding tiers beyond what the problem needs:

    • Each layer just forwards calls to the next with no transformation or value
    • Simple read requires touching 6+ classes across 4 layers
    • Remedy: Collapse pass-through layers; keep only layers that carry real responsibility

    Over-Abstraction

    Abstraction piled on until the code is impossible to follow:

    • Excessive interfaces, generics, factories, and indirection for single implementations
    • You can't tell what actually runs without stepping through many hops
    • Remedy: Inline single-implementation abstractions; abstract only at real variation points (rule of three)

    Futuristic Architecture

    Solution built for imagined future requirements that no one can actually predict:

    • Extensibility points, plugin systems, config knobs nothing uses
    • Most speculative flexibility is wasted effort — closely related to Speculative Generality and YAGNI
    • Remedy: Build for today's known requirements; add flexibility when a real second case arrives

    Technology-Enthusiast Architecture

    New/shiny technology put into production because the architect liked it:

    • Unproven tech adopted without validating it fits the problem or scales
    • Chasing trends over stability
    • Remedy: Evaluate tech against actual requirements; prefer proven tools; prototype before committing

    Overkill Architecture

    A simple problem solved with a disproportionate amount of architecture and technology:

    • Microservices, event sourcing, k8s for a CRUD app with a handful of users
    • Remedy: Match architecture weight to problem size (KISS); start simple, evolve when justified

    Cloud / Visio Architecture

    "Architecture" that exists only in nice diagrams, disconnected from the code and runtime reality:

    • Diagrams don't match what's actually deployed; boxes and arrows with no code correspondence
    • Remedy: Keep architecture docs grounded in and verified against the real system

    Note on the opposite extreme: total lack of architecture (no boundaries, no structure) is equally a smell — see Big Ball of Mud and Missing Architecture. Both under- and over-engineering are failures.

    Coupling & Cohesion Smells

    Circular Dependencies

    Module A → Module B → Module A. Detected via:

    • Import graph analysis
    • "Cannot access before initialization" errors
    • Remedy: Extract shared interface/common module, apply dependency inversion

    Content Coupling

    One module directly modifying another's internal state. Signs:

    • Direct field access across module boundaries
    • friend/package-private abuse
    • Remedy: Use public APIs, encapsulate internal state

    Common Coupling (Global State)

    Multiple modules depending on shared global mutable state:

    • Global variables, singletons with mutable state
    • Ambient context (e.g., CurrentUser static property)
    • Remedy: Parameterize, use dependency injection, make state explicit

    Stamp Coupling

    Passing entire data structures when only a few fields needed:

    • Functions receiving large DTOs but using one field
    • Remedy: Create focused parameters or smaller interfaces (ISP)

    Shotgun Surgery

    A single change requires modifications across many files:

    • Adding a field touches 5+ files in different modules
    • Remedy: Consolidate related behavior, apply Single Responsibility

    Feature Envy

    A method that uses another class's methods more than its own:

    • Method calls other.foo(), other.bar(), other.baz() with few self-calls
    • Remedy: Move the method to the class it envies

    Data Clumps

    Same group of fields appearing together in multiple places:

    • (street, city, zip) appearing in 5 method signatures
    • Remedy: Extract into a value object

    Divergent Change

    One module/class is repeatedly changed for many unrelated reasons (the opposite of Shotgun Surgery):

    • "I always change these three methods for DB changes, and those two for UI changes" in the same class
    • Remedy: Split the class along its axes of change (Single Responsibility)

    Inappropriate Intimacy

    Two classes are too entangled with each other's internals:

    • Reaching into another class's private fields, tight bidirectional references
    • Remedy: Move methods/fields to the class they belong to, extract a shared class, or replace with delegation

    Message Chains

    Long navigation chains like a.getB().getC().getD().doThing():

    • Client coupled to the whole object graph; violates the Law of Demeter
    • Remedy: Hide delegation — add a method on the first object that returns what the client needs

    Middle Man

    A class that delegates almost all of its work to another class:

    • Most methods just forward calls; adds indirection without value
    • Remedy: Remove the middle man and let clients talk to the real object (inline the delegation)

    Parallel Inheritance Hierarchies

    Every time you add a subclass to one hierarchy, you must add one to another:

    • Shape/ShapeRenderer, Employee/EmployeePermission growing in lockstep
    • Remedy: Merge hierarchies or make one hierarchy reference the other instead of mirroring it

    Code-Level Smells

    Long Method

    • Methods > 50 lines (or whatever suits the language)
    • Deep nesting > 3 levels
    • Multiple levels of abstraction mixed
    • Remedy: Extract methods at same abstraction level, compose

    Long Parameter List

    • Methods with > 4 parameters
    • Boolean flags controlling behavior
    • Remedy: Introduce parameter object, split method, remove flag arguments

    Duplicated Code

    • Identical or near-identical logic in 3+ places
    • Copy-paste with slight variations
    • Remedy: Extract shared method, apply Template Method or Strategy pattern

    Primitive Obsession

    Using primitives instead of domain types:

    • string for Email, PhoneNumber, URL
    • int for Money, Age, Quantity
    • decimal without Currency context
    • Remedy: Create value objects with validation and behavior

    Magic Numbers/Strings

    • Hardcoded literals without explanation
    • if (status == 3) instead of if (status == Status.COMPLETED)
    • Remedy: Extract named constants or enums

    Comments as Deodorant

    • Comments that explain what code does (code should be self-documenting)
    • Commented-out code blocks
    • "TODO" comments accumulating without resolution
    • Remedy: Refactor to make code clear, delete dead code, track TODOs as issues

    Deep Nesting (Arrow Anti-Pattern)

    Loops and conditionals nested so deeply the code drifts rightward into an "arrow" shape:

    • if { if { for { if { ... } } } } — hard to trace which conditions hold at any point
    • Usually > 3 levels of indentation in one function
    • Remedy: Guard clauses / early returns, extract nested blocks into methods, invert conditions, replace conditional with polymorphism

    Dead Code

    • Unused imports, variables, functions
    • Unreachable branches
    • Commented-out code in version control
    • Remedy: Delete it (git history preserves it if needed)

    Data Class

    A class that is only fields plus getters/setters, with no meaningful behavior:

    • A "data bag" other classes reach into and manipulate from outside
    • Closely related to Anemic Domain Model at the class level
    • Remedy: Move the behavior that operates on the data into the class ("Tell, Don't Ask")

    Lazy Class

    A class/module that no longer does enough to justify its existence:

    • Left over after refactoring, or an abstraction that never grew
    • Remedy: Inline it into its caller or collapse the hierarchy

    Speculative Generality

    Abstractions, hooks, parameters, or generics added for hypothetical future needs:

    • Unused abstract base classes, unused parameters, "just in case" configuration
    • Violates YAGNI
    • Remedy: Remove unused abstraction; add it when a real second use case appears

    Temporary Field

    An instance field that is only set/used in certain circumstances and empty otherwise:

    • Fields populated only during one algorithm, confusing readers the rest of the time
    • Remedy: Extract the field + the methods that use it into their own class (Extract Class / introduce a Method Object)

    Testing Smells

    No Tests

    • Modules with zero test coverage
    • Business logic without unit tests
    • Remedy: Write characterization tests first, then add behavior tests

    Test-Implementation Coupling

    • Tests asserting internal method calls, private state, or implementation details
    • Tests breaking on refactoring without behavior changes
    • Remedy: Test through public APIs, assert behavior not implementation

    Test Environment Dependency

    • Tests depending on file system, network, database, system clock without mocking
    • Non-deterministic tests (flaky tests)
    • Remedy: Use test doubles, control environment, use DI

    Complexity Smells (Algorithmic Anti-Patterns)

    A static complexity pattern is a candidate, not proof of a bottleneck. Apply Measure First:

    1. Establish actual input size, call frequency, I/O latency, and whether the path is hot.
    2. Prefer a profiler, representative benchmark, query log, trace, or explicit operation count.
    3. Promote the candidate to a finding only when the workload and impact justify it.
    4. Re-measure the same workload after a fix; without a baseline, do not claim a performance improvement.

    For every complexity candidate, state what to measure, when it becomes a finding, and when not to flag it. Keep the Big-O analysis and correctness checks below, but do not infer severity from syntax alone.

    Nested Loops (O(n^2) and Worse)

    Two or more loops nested inside each other, producing polynomial complexity.

    • Detection: for/while inside another for/while; forEach/map inside forEach/map; loop containing another loop (any depth)
    • Impact: O(n^2) for double-nested, O(n^3) for triple; explodes with moderate data sizes
    • Remedy:
      • Build a Map/Set index for the inner collection → O(n+m)
      • Sort + two-pointer approach → O(n log n)
      • Group/bucket data before iterating
      • Sweep-line for interval/range problems
    • Correctness checks: Does order matter? Are there duplicate keys? Is the original picking first/last/all matches?

    N+1 Query Pattern

    A database query, API call, or I/O operation inside a loop body.

    • Detection: fetch()/axios()/query()/execute()/findMany()/findOne()/findUnique()/select()/where() inside any loop construct
    • Impact: 1 + N round-trips instead of 1; network latency multiplied by item count
    • Remedy:
      • Batch fetch by IDs: SELECT * FROM x WHERE id IN (...) then join in memory
      • Use ORM eager-loading / include / preload / DataLoader
      • Bulk API endpoints accepting arrays
      • Preserve: auth filters, tenancy isolation, ordering, pagination, error semantics
    • Correctness checks: Don't fetch records the original per-item logic wouldn't authorize; preserve missing-record behavior

    Repeated Linear Scan (Missing Index)

    Linear search (includes, indexOf, .find, in_array) inside a loop, where a Set/Map would give O(1) lookup.

    • Detection: .includes() / .indexOf() / .find() / .findIndex() / in_array() / contains() inside a loop body
    • Impact: O(n*m) instead of O(n+m) — each iteration scans the entire collection
    • Remedy: Build a Set (for membership) or Map (for key→value lookup) once before the loop
    • Correctness checks: Does equality semantics change after Set conversion? JavaScript object identity vs. value equality; Python hashability

    Sort-in-Loop

    Sorting inside a loop body, repeating O(n log n) work unnecessarily.

    • Detection: .sort() / sorted() / sort() inside any iterative block
    • Impact: O(k * n log n) instead of O(n log n) — sort repeated k times
    • Remedy:
      • Sort once outside the loop
      • Maintain a heap (PriorityQueue) if incremental top-K is needed
      • Use binary search/insertion into sorted collection
    • Correctness checks: Is each intermediate sorted state externally observable? Does comparator depend on loop-local state?

    Render-Path Recompute (UI Complexity)

    Expensive data transformation (filter→map→sort chains) inside UI component render bodies, recomputed on every render.

    • Detection: .filter().map().sort().reduce() chains inside React/Vue/Svelte component function bodies; inside function Component() or const Component = () => in JSX/TSX
    • Impact: Re-derivation on every state change even if inputs unchanged; jank with large collections
    • Remedy:
      • useMemo / computed / derived with correct dependency arrays
      • Move derivation to selectors, loaders, or server-side
      • Virtualize long lists (windowing)
      • Stabilize callbacks and object props only when child renders are affected
    • Correctness checks: Dependency arrays must include every semantic input; memoization must not hide mutations of mutable inputs

    Pairwise Comparison

    Comparing every element with every other element using double-nested iteration.

    • Detection: Two nested loops iterating the same or similar collections, comparing pairs
    • Impact: O(n^2) for pair matching, overlap detection, conflict checking, nearest-neighbor
    • Remedy:
      • Sort + two-pointer for pair/range matching
      • Sweep-line for interval overlaps
      • Spatial hashing or grid bucketing for proximity
      • Union-find for connectivity
    • Correctness checks: Order stability; tie-breaking in equality cases

    Unnecessary Recompute (Missing Memoization)

    Same pure computation repeated with same inputs without caching.

    • Detection: Identical function calls with same arguments in hot paths; repeated expensive transforms; recursive calls without memoization
    • Impact: Linear/polynomial wasted work; especially bad with recursive Fibonacci-style patterns (O(2^n) → O(n) with memo)
    • Remedy: Add memoization/caching with proper invalidation; use lru_cache/memoize/useMemo as appropriate

    Wrong Data Structure

    Using a suboptimal data structure for the access pattern.

    • Detection:
      • Array/List used for frequent membership tests → should be Set
      • Array/List used for key-value lookups → should be Map/Object
      • Array used as queue with shift()/pop(0) (O(n) per dequeue) → should use proper Queue
      • Sorted insertion into array (O(n) per insert) → should use Heap
    • Remedy: Replace with the data structure whose complexity matches the access pattern:
      • Set → O(1) has/add/delete
      • Map → O(1) get/set
      • Heap → O(log n) push/pop for priority
      • Queue/Deque → O(1) enqueue/dequeue

    What NOT to Flag

    • Cold paths: Complexity that only runs on startup, config loading, or tiny N (< 100) is rarely worth fixing
    • Intentional tradeoffs: Clear, readable O(n) code where O(n log n) would add complexity with no measurable gain
    • Already optimized: Map/Set already in use; batch loading already implemented; memoization already present

    Design Principle Violations

    Use the canonical matrix in Step 3 as the reporting contract. These design checks refine candidate detection; they do not create one finding per principle.

    • SOLID umbrella: Use only when multiple SOLID concerns share one root cause or a narrower lens is not reliable.
    • SRP: Confirm independent reasons to change; size alone is insufficient.
    • OCP: Confirm repeated edits for a real variant; do not replace a simple local conditional with speculative polymorphism.
    • LSP: Subtypes must preserve the base contract's preconditions, postconditions, and invariants. Report as SOLID/LSP.
    • ISP: Confirm clients depend on methods they do not use. Report as SOLID/ISP.
    • DIP: Confirm high-level policy is coupled to concrete mechanism in a way that harms testing or replacement; a single implementation does not automatically justify an interface.
    • DRY: Deduplicate shared knowledge, not coincidentally similar syntax.
    • KISS and YAGNI: Reject abstractions whose future variation or leverage is not demonstrated.
    • Composition: Prefer it when inheritance exposes unwanted behavior or binds independent variation axes—not as a mechanical rule.
    • Separation of Concerns: Confirm policy, presentation, persistence, or I/O leakage across an intended boundary.
    • Fail Fast: Detect invalid state near its source while preserving established error, retry, transaction, and cleanup semantics.
    • Measure First: Lower unmeasured optimization claims to candidates instead of reporting a second "principle violation."

    Object-Orientation Abusers (from Fowler / refactoring.guru)

    Switch Statements (Type-Code Conditionals)

    Repeated switch/if-else chains that branch on a type code or enum:

    • The same conditional structure duplicated in several places
    • Adding a new type forces editing every switch (OCP violation)
    • Remedy: Replace conditional with polymorphism (Strategy/State), or Replace Type Code with Subclasses
    Refused Bequest

    A subclass inherits methods/fields it doesn't need:

    • Overrides inherited methods to throw, no-op, or do something unrelated
    • Signals the inheritance relationship is wrong
    • Remedy: Push down unused members, or replace inheritance with delegation
    Alternative Classes with Different Interfaces

    Two classes perform the same role but expose differently-named methods:

    • sort() vs arrange(), getUser() vs fetchUser() for interchangeable classes
    • Remedy: Unify the interface (rename methods, extract a common superclass/interface)
    Incomplete Library Class

    A third-party/library class lacks methods you need and can't be modified:

    • Scattered helper functions or copy-paste wrappers around the library
    • Remedy: Introduce a Foreign Method or wrap it in an adapter/local extension class

    Other refactoring.guru smells are documented in their thematic sections above: Divergent Change, Data Class, Lazy Class, Speculative Generality, Temporary Field, Parallel Inheritance Hierarchies, Inappropriate Intimacy, Message Chains, and Middle Man.


    Edge Cases & Fallback

    ScenarioHandling
    User doesn't specify scopeDefault to recent changes (git diff) for repos > 200 files, full analysis otherwise
    Project has no clear architectureReport "Big Ball of Mud" with evidence, recommend incremental refactoring
    Empty/monorepo projectReport that architecture analysis requires code; ask user to specify module
    Language not supportedReport general structural observations; note language-specific checks are limited
    Report file path conflictsAppend -2, -3, etc. to filename
    User wants a quick checkRun only Critical-level scans, skip Code and Naming categories
    User wants only one categoryFocus analysis on that category, skip others

    Report Output Example

    🔍 Architecture Smell Analysis Complete
    
    Project: goal-workflow
    Style: Modular Monolith (with some layering violations)
    Files Analyzed: 47
    Health: 🟡 Fair
    
    Critical: 3  |  Warnings: 6  |  Suggestions: 9
    
    🔴 Critical Issues:
      1. Anemic Domain Model — `models/` classes have only getters/setters,
         all logic in `services/`. Violates DDD Rich Domain Model principle.
      2. N+1 Query Pattern — `services/order.ts:142` fetches user per order in loop;
         should batch-load users by IDs (O(n*m) → O(n+m)).
      3. Static Cling — `util/ApiClient.ts` uses all static methods,
         making consumer code untestable.
    
    🟡 Warnings:
      1. God Object — `services/workflow.ts` at 847 lines handles too many concerns
      2. Nested Loop O(n^2) — `analytics.ts:89` pairwise comparison of events;
         sort+two-pointer would be O(n log n)
      3. Leaky Abstraction — `repositories/user.ts` exposes MongoDB query syntax
      4. Duplicated Code — validation logic duplicated across 4 controllers
      5. Circular Dependency — `auth` ↔ `user` modules depend on each other
      6. Magic Numbers — ~23 hardcoded values without named constants
    
    Full report: tasks/smell-report-2026-05-27-1530.md
    

    Frequently asked questions

    What to verify before installation and use

    What does the smell source document cover?

    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.

    How do I install smell?

    The source record exposes this install command: npx skills add https://github.com/smallnest/goal-workflow --skill "skills/smell". Inspect the command and pinned source before running it.

    Which permission-related actions were detected?

    Static rules flagged read-files, network in the source; the page lists the matching lines and excerpts.

    Alternatives

    Compare before choosing

    Computed 10045,511

    coreyhaines31/marketingskills

    ab-testing

    When the user wants to plan, design, or implement an A/B test or experiment, or build a growth experimentation program. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "should I test this," "which version is better," "test two versions," "statistical significance," "how long should I run this test," "growth experiments," "experiment velocity," "experiment backlog," "ICE score," "experimentation program

    Computed 1008

    narrative-io/narrative-skills-marketplace

    design-analysis

    Translate a fuzzy analytical question into a rigorous investigation plan. Interrogates the ask, grounds the plan in the available data dictionary, applies analytical best practices, and produces a structured brief of query specifications for a downstream query-writing skill. Plans, does not write SQL. Use when: "why did X drop", "is there a relationship between A and B", "who are our highest-value customers", "what's driving the change in Y", "investigate this trend", "design an analysis for", "

    Computed 97269

    Aperivue/medsci-skills

    calc-sample-size

    Interactive sample size calculator for medical research. Decision-tree guided test selection, reproducible R/Python code, effect size interpretation, and IRB-ready justification text. Supports diagnostic accuracy, agreement, proportions, continuous outcomes, survival, ANOVA, logistic regression, and non-inferiority/equivalence designs.

    Computed 97223

    yonatangross/orchestkit

    verify

    Grade work that already exists and decide whether it can merge. Runs the project's current unit, integration, and E2E suites plus security scanning and type checking, scores every dimension 0-10, and returns a merge verdict with a VERIFIED-vs-CLAIMED evidence manifest. Writes no test files and edits no source. Use when verifying changes are ready to merge. Use /ork:cover instead when the tests still have to be written.