YAGNI Violations: 36 Single-Implementation Interfaces and the Cost of Over-Engineering
A static analysis audit identified 36 interface abstractions in LEO's codebase that had only one implementation — and 3 with zero implementations — representing YAGNI violations that added 754 lines of unnecessary abstraction code.
- Reference
- L012
- Project
- LEO
- Status
- Documented
- Evidence
- high
- Source
- 012-yagni-violations-interface-over-engineering.md
Context
The ponytail audit report (ponytail_audit_report.txt) summarized an automated scan that found interfaces with insufficient implementation diversity to justify their abstraction overhead.
The Question
How widespread was unnecessary abstraction (interfaces with single or zero implementations) in the LEO codebase?
Findings
The audit identified 36 YAGNI violations of two types:
Type 1: Interfaces with exactly 1 implementation (could be a direct class)
Examples:
Interface IDocumentRepository→ 1 impl:SQLDocumentRepository— inbackend/app/document/repository.pyInterface IExpressionRepository→ 1 impl:SQLExpressionRepository— inbackend/app/expression/repository.pyInterface IEngine→ 1 impl:BaseEngine— inbackend/app/platform/core/engine.pyInterface EventStore→ 1 impl:InMemoryEventStore— inbackend/app/realtime/store/interface.pyInterface TransportAdapter→ 1 impl:WebSocketTransport— inbackend/app/realtime/interfaces/transport.pyInterface TaskQueue→ 1 impl:PostgresTaskQueue— inbackend/app/platform/worker/queue_interface.pyInterface ISkillRepository→ 1 impl:ISkillStore— inbackend/app/skills/repositories/interfaces.pyInterface IEngineeringStore→ 1 impl:SQLEngineeringStore— inbackend/app/engineering/interfaces.pyInterface RoutingPolicy→ 1 impl:WeightedRoutingPolicy— inbackend/app/skills/routing/policies.py- (26 more similar cases)
Type 2: Interfaces with 0 implementations (dead abstractions)
Interface ISkillPlugin→ 0 impls — inbackend/app/skills/plugins/base.pyInterface RealtimeMiddleware→ 0 impls — inbackend/app/realtime/middleware/interface.pyInterface ILoggingService→ 0 impls — inbackend/app/cognition/kernel/services.pyInterface IConfigurationService→ 0 impls — inbackend/app/cognition/kernel/services.pyInterface ITimeService→ 0 impls — inbackend/app/cognition/kernel/services.pyInterface IHealthService→ 0 impls — inbackend/app/cognition/kernel/services.py
There was also 1 Factory YAGNI violation:
Factory SkillFactory→ could be replaced with direct instantiation — inbackend/app/skills/factory.py
Total estimated reduction: -754 lines, -0 deps possible
Evidence
ponytail_audit_report.txt— 37 YAGNI violations with file paths and replacement suggestions
Diagnosis
Established: 36 interfaces exist in the codebase with 0 or 1 implementations. These represent abstraction overhead without polymorphism benefit.
Likely: The interface-first pattern was applied uniformly during development — every repository, store, engine, and adapter got an interface definition regardless of whether multiple implementations were ever planned. This is a natural consequence of engineering discipline applied too broadly.
The 4 zero-implementation interfaces in backend/app/cognition/kernel/services.py (ILoggingService, IConfigurationService, ITimeService, IHealthService) are particularly notable — they were defined in the cognitive kernel's services module but never implemented, suggesting planned but unrealized cognitive kernel services.
Unknown: Whether any of the single-implementation interfaces were planned to have additional implementations in future phases (making the abstraction forward-looking rather than wasteful).
What Changed
No documented corrective action. The audit summary states "-754 lines possible" — the reduction was calculated but not executed.
What I Learned
Interface-first design is appropriate when multiple implementations are planned or when the interface represents a boundary between independently testable components. When applied to every repository and store uniformly, it creates abstraction overhead that adds cognitive load without providing polymorphism value.
The 4 zero-implementation interfaces in the cognitive kernel services are the most telling: they represent architectural intent (planned services) that was documented as interfaces but never realized.
What I Would Do Differently
Hindsight observation: Apply the interface-first pattern selectively — to components that genuinely need to be tested in isolation with mocks, or that genuinely expect multiple implementations. For internal repositories with a single backing store, a concrete class is simpler and more maintainable.
Broader Principle
YAGNI applies to abstractions as much as to features. An interface with one implementation is a concrete class written twice. Create abstractions when there is evidence of polymorphism need, not speculatively.
Technical References
ponytail_audit_report.txtbackend/app/cognition/kernel/services.pybackend/app/skills/repositories/interfaces.pybackend/app/engineering/interfaces.py
Failure sequence
On the record- Attempt
- How widespread was unnecessary abstraction (interfaces with single or zero implementations) in the LEO codebase?
- Failure
- The audit identified 36 YAGNI violations of two types: **Type 1: Interfaces with exactly 1 implementation (could be a direct class)** Examples: - `Interface IDocumentRepository` → 1 impl: `SQLDocumentRepository` — in `backend/app/document/repository.py` - `Interface IExpressionRepository` → 1 impl: `SQLExpressionRepository` — in `backend/app/expression/repository.py` - `Interface IEngine` → 1 impl: `BaseEngine` — in `backend/app/platform/core/engine.py` - `Interface EventStore` → 1 impl: `InMemoryEventStore` — in `backend/app/realtime/store/interface.py` - `Interface TransportAdapter` → 1 impl: `WebSocketTransport` — in `backend/app/realtime/interfaces/transport.py` - `Interface TaskQueue` → 1 impl: `PostgresTaskQueue` — in `backend/app/platform/worker/queue_interface.py` - `Interface ISkillRepository` → 1 impl: `ISkillStore` — in `backend/app/skills/repositories/interfaces.py` - `Interface IEngineeringStore` → 1 impl: `SQLEngineeringStore` — in `backend/app/engineering/interfaces.py` - `Interface RoutingPolicy` → 1 impl: `WeightedRoutingPolicy` — in `backend/app/skills/routing/policies.py` - (26 more similar cases) **Type 2: Interfaces with 0 implementations (dead abstractions)** - `Interface ISkillPlugin` → 0 impls — in `backend/app/skills/plugins/base.py` - `Interface RealtimeMiddleware` → 0 impls — in `backend/app/realtime/middleware/interface.py` - `Interface ILoggingService` → 0 impls — in `backend/app/cognition/kernel/services.py` - `Interface IConfigurationService` → 0 impls — in `backend/app/cognition/kernel/services.py` - `Interface ITimeService` → 0 impls — in `backend/app/cognition/kernel/services.py` - `Interface IHealthService` → 0 impls — in `backend/app/cognition/kernel/services.py` There was also 1 Factory YAGNI violation: - `Factory SkillFactory` → could be replaced with direct instantiation — in `backend/app/skills/factory.py` **Total estimated reduction:** -754 lines, -0 deps possible
- Diagnosis
- **Established:** 36 interfaces exist in the codebase with 0 or 1 implementations. These represent abstraction overhead without polymorphism benefit. **Likely:** The interface-first pattern was applied uniformly during development — every repository, store, engine, and adapter got an interface definition regardless of whether multiple implementations were ever planned. This is a natural consequence of engineering discipline applied too broadly. The 4 zero-implementation interfaces in `backend/app/cognition/kernel/services.py` (`ILoggingService`, `IConfigurationService`, `ITimeService`, `IHealthService`) are particularly notable — they were defined in the cognitive kernel's services module but never implemented, suggesting planned but unrealized cognitive kernel services. **Unknown:** Whether any of the single-implementation interfaces were planned to have additional implementations in future phases (making the abstraction forward-looking rather than wasteful).
- Lesson
- Interface-first design is appropriate when multiple implementations are planned or when the interface represents a boundary between independently testable components. When applied to every repository and store uniformly, it creates abstraction overhead that adds cognitive load without providing polymorphism value. The 4 zero-implementation interfaces in the cognitive kernel services are the most telling: they represent architectural intent (planned services) that was documented as interfaces but never realized.
- Next iteration
- No documented corrective action. The audit summary states "-754 lines possible" — the reduction was calculated but not executed.