← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Speculative Generality

Code Quality Intermediate
debt(d5/e3/b5/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5), because detection_hints.tools lists phpstan, phpmd, and php-dead-code — specialist static analysis tools that can flag abstract classes with single implementations, unused parameters, and dead code patterns. Standard linters won't catch these automatically; targeted SAST/dead-code tools are required.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3), grounded in quick_fix which says to delete the abstract base class, plugin system, or unused configuration. Each removal is typically a focused deletion within one component — not a one-liner but also not cross-cutting; removing a speculative abstraction touches one area and its callsites but doesn't require sweeping multi-file architectural changes.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5), because speculative abstractions apply across web, cli, and queue-worker contexts and impose ongoing cognitive overhead on every maintainer who encounters them. They slow down multiple work streams by forcing devs to navigate layers of indirection with no current value, but they don't fully define the system's shape — removal is painful but feasible without rewriting everything.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7), grounded in the misconception field: 'Adding flexibility upfront saves refactoring time later.' This directly contradicts the well-established YAGNI principle and the real-world observation that speculative abstractions almost always need redesign anyway when real requirements arrive. A competent developer may sincerely believe they are doing the right thing by future-proofing, making this a habitual and hard-to-unlearn mistake that contradicts sound software engineering practice.

About DEBT scoring →

Also Known As

over-engineering YAGNI violation future-proofing smell

TL;DR

Unused abstractions, parameters, or hooks added for hypothetical future use that complicate the codebase without present value.

Explanation

Speculative generality is the code smell version of over-engineering: creating abstract classes with one subclass, adding unused parameters for flexibility, or writing hook points for requirements that don't exist yet. It violates YAGNI and adds cognitive overhead for every reader. Remove unused abstractions, parameters, and delegate methods that serve no current purpose — refactoring tools make re-introducing them straightforward if the need genuinely arises.

Common Misconception

Adding flexibility upfront saves refactoring time later. Speculative abstractions are rarely used as anticipated, add cognitive load now, and often need to be redesigned anyway when real requirements arrive — YAGNI exists because the cost of speculative code is immediate and certain.

Why It Matters

Code written for imagined future requirements adds complexity now for no current value — if the requirement never materialises, the abstraction is dead weight that obstructs simpler solutions.

Common Mistakes

  • Adding abstract base classes 'in case we need another implementation later' with only one concrete class.
  • Plugin architectures for internal code that never needs to be pluggable.
  • Configuration files for behaviour that has never varied and shows no sign of varying.
  • Not applying YAGNI — the cost of adding abstraction when needed is almost always less than carrying premature abstraction.

Code Examples

💡 Note
Speculative abstractions add complexity now for benefits that may never arrive. Refactor when the second real case exists.
✗ Vulnerable
// Built for flexibility nobody asked for yet
interface AbstractDataProviderFactoryInterface {
    public function create(string $type): DataProviderInterface;
}
class ConcreteDataProviderFactory implements AbstractDataProviderFactoryInterface {
    public function create(string $type): DataProviderInterface {
        return new DatabaseDataProvider(); // only one type ever exists
    }
}
✓ Fixed
// YAGNI — build what's needed today
class DatabaseDataProvider {
    public function getData(): array { return $this->db->fetchAll(); }
}
// Add the interface/factory if and when a second provider materialises

Added 15 Mar 2026
Edited 12 Jun 2026
Views 50
AI edit PF Media Bot Claude Opus 4.5 on refs · 28 Apr 2026
Edits history 1 edit
  1. refs PF Media Bot Claude Opus 4.5 · 28 Apr 2026
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 0 pings W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 0 pings S 2 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 1 ping T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 0 pings W
No pings yet today
PetalBot 1
Amazonbot 8 SEMrush 5 Scrapy 5 Ahrefs 4 Perplexity 3 Google 3 Unknown AI 2 Claude 2 Bing 2 ChatGPT 2 Meta AI 1 PetalBot 1
crawler 34 crawler_json 4
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Delete the abstract base class with one concrete implementation, the plugin system with zero plugins, and the configuration option nobody uses — remove code for future requirements that may never come
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Abstract class with single implementation; interface only ever implemented once; method parameter never used by any caller; over-engineered config system
Auto-detectable: ✓ Yes phpstan phpmd php-dead-code
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Medium Context: Class Tests: Update


✓ schema.org compliant