solid-principles/SKILL.md
Enforces SOLID principles (SRP, OCP, LSP, ISP, DIP) in object-oriented and multi-paradigm code. Use when designing classes and interfaces, evaluating responsibility assignment, reviewing code for coupling issues, applying dependency inversion, refactoring fat interfaces, or checking that subtypes are truly substitutable.
npx skillsauth add kayaman/skills solid-principlesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Reference: Clean Architecture (Martin), Practical Object-Oriented Design (Metz), Code That Fits in Your Head (Seemann)
Refined definition (Martin, 2017): "A module should be responsible to one, and only one, actor."
SRP is about people and change reasons, not "doing one thing." A class violates SRP when changes requested by different stakeholders (actors) would modify the same class.
Classic example: An Employee class with calculatePay() (CFO's team), reportHours() (COO's team), and save() (CTO's team). A shared regularHours() method creates accidental coupling — when the CFO's team changes the pay calculation, the COO's hours report silently breaks.
"Software entities should be open for extension, but closed for modification."
Achieve this through abstract interfaces and polymorphism, not inheritance hierarchies. New behavior is added by creating new implementations, not by modifying existing code.
if/else or switch chains that check type| Violation Signal | Remedy |
|-----------------|--------|
| switch on type or enum to decide behavior | Extract interface; create implementations per case |
| Adding a new feature requires modifying existing classes | Introduce abstraction at the variation point |
| Shotgun surgery — one change touches many files | Consolidate related behavior behind a single interface |
Liskov (1987): Subtypes MUST be substitutable for their base types without altering program correctness.
This is behavioral subtyping — semantic, not just syntactic. The compiler won't catch most violations.
| Constraint | Rule | |-----------|------| | Preconditions | A subtype MUST NOT strengthen preconditions (cannot require more from callers) | | Postconditions | A subtype MUST NOT weaken postconditions (must deliver at least what the parent promises) | | Invariants | A subtype MUST preserve all invariants of the parent type | | History Constraint | A subtype MUST NOT allow state changes the parent would not allow |
Square cannot be a subtype of Rectangle because setting width independently of height violates Rectangle's behavioral contract (width and height are independent). The "is-a" relationship in the real world does not imply "is-a-subtype" in code.
UnsupportedOperationException or NotImplementedException in subtype methods — this is an LSP violation"No client should be forced to depend on methods it does not use."
Fat interfaces force implementors to provide dummy implementations or throw exceptions for methods they don't need — violating both ISP and LSP.
Printable, Serializable, ForPlacingOrders — not by implementation: PrinterInterface| Violation Signal | Remedy |
|-----------------|--------|
| Implementors throw UnsupportedOperationException for some methods | Split into role interfaces; implement only what applies |
| Interface has methods used by different, unrelated clients | Extract client-specific interfaces |
| A change to one method forces recompilation of unrelated clients | Segregate into independent interfaces |
Two parts:
| Term | What It Is | Level | |------|-----------|-------| | DIP | Design principle — depend on abstractions, not concretions | Architecture principle | | DI (Dependency Injection) | Pattern — supply dependencies from outside via constructor, setter, or method | Implementation technique | | IoC (Inversion of Control) | Paradigm — framework calls your code, not the other way around | Broad principle |
new ConcreteService())SRP ──enables──▶ OCP (single-responsibility classes are extended, not modified)
DIP ──enables──▶ OCP (abstractions allow substitutable implementations)
LSP ──ensures──▶ OCP extensions don't break behavior
ISP ──prevents─▶ LSP violations (no unsupported methods forcing dummy implementations)
All five principles converge on one practice: program to an interface.
| Principle | FP Equivalent | |-----------|--------------| | SRP | Functions and modules have a single purpose | | OCP | Higher-order functions extend behavior without modifying existing functions | | LSP | Function signatures are contracts; substituting compatible functions preserves correctness | | ISP | Modules export only what consumers need; minimal public APIs | | DIP | Pass functions as parameters instead of depending on concrete implementations |
| Principle | Microservice Equivalent | |-----------|------------------------| | SRP | Each service owns a single business capability | | OCP | Stable API contracts; new behavior via new endpoints or new services | | LSP | Consumer-driven contract tests verify substitutability | | ISP | Minimal endpoint surface per service; BFF pattern for client-specific APIs | | DIP | Message queues and event buses as abstractions between services |
SOLID principles are guidelines, not rigid rules. Apply them where complexity warrants it.
When designing or reviewing code, verify:
UnsupportedOperationException, no weakened contracts| Book | Author(s) | Publisher | Year | |------|-----------|-----------|------| | Agile Software Development: Principles, Patterns, and Practices | Robert C. Martin | Pearson | 2002 | | Clean Architecture | Robert C. Martin | Pearson | 2017 | | Practical Object-Oriented Design (2nd ed.) | Sandi Metz | Addison-Wesley | 2018 | | Code That Fits in Your Head | Mark Seemann | Addison-Wesley | 2021 | | A Philosophy of Software Design (2nd ed.) | John Ousterhout | Stanford | 2021 | | Object-Oriented Software Construction | Bertrand Meyer | Prentice Hall | 1997 | | Get Your Hands Dirty on Clean Architecture (2nd ed.) | Tom Hombergs | Packt | 2023 |
tools
Guidance for designing charts, graphs, plots, dashboards, and data visualizations that communicate clearly and persuade. Use when creating or reviewing a visualization, choosing a chart type, picking a color palette, decluttering a busy graphic, fixing misleading axes or proportions, building a dashboard, annotating a figure, or turning data into a presentation, report, or data-driven story. Grounded in the standard data-visualization literature (Knaflic, Tufte, Cleveland & McGill, Cairo, Wilke, Munzner, Few, Berinato). Covers chart selection, graphical perception and encoding, color and accessibility, decluttering, graphical integrity, dashboards, and narrative. Does NOT cover building data pipelines or ETL, statistical modeling or analysis methods, BI tool/vendor selection, or general UI/UX layout (see ux-design-principles). Tool-agnostic, with optional Python recipes.
development
Architect and implement production-grade microservices systems in TypeScript (NestJS) and Python (FastAPI), including resilience, observability, testing, deployment, and migration guidance.
development
--- name: databricks-genie-spaces-best-practices description: Design, configure, curate, govern, monitor, and integrate Databricks AI/BI Genie Spaces — the natural-language-to-SQL surface over Unity Catalog. Covers space scoping, general instructions, parameterized example SQL, SQL functions, trusted assets, JOIN configuration, knowledge store, certified queries, benchmarks, monitoring tab, feedback loops, the Genie Conversation API, governance via Unity Catalog (row filters, column masks, embed
tools
Implement OTP and passwordless authentication on AWS for TypeScript projects using Cognito CUSTOM_AUTH triggers (default) or a custom DynamoDB-backed flow, with SES (email) and SNS (SMS) delivery. Use when the user mentions OTP, one-time password, passwordless login, magic link, Cognito custom auth, DefineAuthChallenge, CreateAuthChallenge, VerifyAuthChallengeResponse, SES verification email, SNS SMS code, or MFA over email/SMS. Covers architecture decision (Cognito vs custom), Lambda trigger handlers, SES/SNS notifiers, DynamoDB schema with TTL, rate limiting, constant-time comparison, threat model (enumeration, replay, brute force), and aws-sdk-client-mock testing.