A code smell hints at a defect — a defect suggests a vulnerability

Stateful code smells stink the loudest

Bugs are not random; they follow patterns. These are the families of stateful defects — how they read on the page, why they happen, and the philosophies that defuse them.

01

Code Smell

A pattern that hints at a structural problem. Rotting code does not cause smells — code causes smells.

02

Software Defect

The latent fault the smell was pointing at. It may pass every test and still be there.

03

Vulnerability

What the defect becomes once it ships and meets the real world.

the catalog

Families of defect

changing the state of a program

Bugs of Mutated State

Bugs caused by changing the state of a program in ways that create unpredictability, where information and control flow become untraced.

  • Wrong or unexpected results
  • Unpredictable function output or operation
  • Edge cases abounding in code
Read the family
consuming unknown input as state

Bugs of Unstructured State

Bugs caused by consuming unknown or inadequately validated input as state, without type checking or structural contracts.

  • Information doesn't fit its expected container
  • Latent, lingering bugs even with more tests
  • Poor big-O performance with respect to input size
Read the family
concurrency and caching of state

Bugs of Shared State

Bugs caused by concurrency, caching, and the distribution of state across multiple independent actors or processes.

  • Data is inaccessible or out of order
  • Resources are slow or unavailable
  • Information is wrong or outdated
Read the family
the everyday smells beneath the stateful ones

Common Software Defects

The everyday defects in every codebase, read by how they're caught: readability smells a reviewer sees (duplication, magic numbers, bad names), correctness bugs tests catch (DRY violations, off-by-one, sloppy error handling), and security defects a scanner finds (SCA, SAST, DAST). Most don't crash on their own -- they make the stateful bugs harder to see, and the worst of them become vulnerabilities.

  • The same change has to be made in several places
  • Numbers and strings with no explanation
  • Names that have to be decoded before they're understood
Read the family
defects that emerge from other defects

Compound Defects

Bugs with no single line number: they emerge where two stateful defects meet. You can only name them by their symptom, because the cause lives in the interaction.

  • The bug cannot be reproduced consistently
  • Whack-a-mole fixes that won't stay fixed
  • Crashes first seen live, in the demo
Read the family
the cascade

This is why we can't have nice things

A code smell is not the bug. It is the smell of one nearby. A defect that ships does not stay a defect. It becomes something an attacker can use.

cascade

Software that crashes becomes a Denial-of-Service attack.

cascade

Edge cases & complexity becomes an Abuse of Terms.

cascade

Race conditions & lag becomes a way to cheat and scam.

// there are two hard problems in computer science:
  1. naming things
  2. off-by-one errors
  3. cache invalidation