xiaohongshu
xiaohongshu
minimal-abstractions
Evaluates and prevents unnecessary abstractions by analyzing interfaces, layers, and patterns against concrete requirements. Use when evaluating new abstractions, reviewing architecture proposals, detecting over-engineering, or simplifying existing code. Triggers on "is this abstraction necessary...
Full skill instructions
Before adding a new abstraction (interface, abstract class, wrapper, layer), ask:
If any answer is "no" or "maybe" → Don't add it. Use the simplest solution that works.
Explicit Triggers (User asks):
Implicit Triggers (Autonomous invocation):
Debugging/Problem Triggers:
This skill provides a systematic framework for:
When evaluating an abstraction:
Abstractions are not free - every interface, wrapper, layer, or pattern adds:
When abstractions ARE valuable:
When abstractions are NOT valuable:
Before creating a new abstraction:
Use this checklist before adding ANY new abstraction (interface, abstract class, wrapper, layer):
Action: If similar abstraction exists → Use it. Don't create a new one.
Action: If <2 implementations → Skip the abstraction. Use concrete implementation directly.
Action: If requirement is speculative → Don't build it yet. Wait for actual need.
Action: If cost > benefit → Simplify. Use direct solution.
Action: If simpler solution exists → Use it.
# ❌ Over-engineered: Interface with only one implementation
class DataProcessor(Protocol):
def process(self, data: dict) -> dict: ...
class JsonDataProcessor: # Only implementation
def process(self, data: dict) -> dict:
return transform_json(data)
Why it's a red flag: No actual polymorphism. The interface adds indirection without benefit.
Better approach:
# ✅ Simple: Direct implementation
def process_json_data(data: dict) -> dict:
return transform_json(data)
# ❌ Over-engineered: Wrapper that just forwards calls
class DatabaseWrapper:
def __init__(self, db: Database):
self._db = db
def query(self, sql: str) -> list:
return self._db.query(sql) # Just forwarding
Why it's a red flag: No transformation, validation, or added behavior. Pure indirection.
Better approach: Use the database directly or add actual value (caching, retry, validation).
# ❌ Over-engineered: Unnecessary service layer
class UserRepository: # Already exists
def get_user(self, id: int) -> User: ...
class UserService: # Adds nothing
def __init__(self, repo: UserRepository):
self.repo = repo
def get_user(self, id: int) -> User:
return self.repo.get_user(id) # Just forwarding
Why it's a red flag: Service layer adds no business logic, validation, or orchestration.
Better approach: Use repository directly until business logic is needed.
# ❌ Over-engineered: Factory for single type
class UserFactory:
@staticmethod
def create_user(name: str, email: str) -> User:
return User(name=name, email=email)
Why it's a red flag: Factory pattern used without variation or complexity justification.
Better approach:
# ✅ Simple: Direct construction
user = User(name="Alice", email="[email protected]")
# ❌ Over-engineered: Generic solution for specific problem
class ConfigLoader(Generic[T]):
def load(self, source: str, parser: Parser[T]) -> T: ...
class JsonParser(Parser[dict]): ...
class YamlParser(Parser[dict]): ...
Why it's a red flag: Generic abstraction built before knowing actual requirements.
Better approach: Start with simple JSON config loader. Generalize when second format is needed.
Over-Engineered:
# Unnecessary: Abstract repository + generic base + implementation
class Repository(Protocol, Generic[T]):
def get(self, id: int) -> T: ...
def save(self, entity: T) -> None: ...
class BaseRepository(Generic[T]): # Generic base
def validate(self, entity: T) -> bool: ...
class UserRepository(BaseRepository[User]): # Concrete
def get(self, id: int) -> User: ...
def save(self, user: User) -> None: ...
Right-Sized:
# Clean Architecture: Protocol in domain, implementation in infrastructure
# domain/repositories.py
class UserRepository(Protocol): # Interface for dependency inversion
def get_user(self, id: int) -> User: ...
def save_user(self, user: User) -> None: ...
# infrastructure/repositories.py
class SqlUserRepository: # Concrete implementation
def get_user(self, id: int) -> User: ...
def save_user(self, user: User) -> None: ...
Over-Engineered:
# Unnecessary: Service that just forwards to repository
class UserService:
def __init__(self, repo: UserRepository):
self.repo = repo
def get_user(self, id: int) -> User:
return self.repo.get_user(id) # No business logic!
Right-Sized:
# Use repository directly until business logic emerges
class AuthenticationHandler:
def __init__(self, user_repo: UserRepository):
self.user_repo = user_repo
def authenticate(self, email: str, password: str) -> Result[User, AuthError]:
user = self.user_repo.get_user_by_email(email)
if not user:
return Err(AuthError.USER_NOT_FOUND)
if not verify_password(password, user.password_hash):
return Err(AuthError.INVALID_PASSWORD)
return Ok(user)
Over-Engineered:
# Project already has Repository pattern
# Adding NEW abstraction for similar purpose:
class DataAccessLayer(Protocol): # Duplicates Repository!
def fetch(self, id: int) -> Entity: ...
def persist(self, entity: Entity) -> None: ...
Right-Sized:
# Use existing Repository pattern
class ProductRepository(Protocol): # Follows project convention
def get_product(self, id: int) -> Product: ...
def save_product(self, product: Product) -> None: ...
This skill complements existing architecture validation skills:
Use with:
architecture-validate-architecture - Check layer boundaries while avoiding unnecessary layersarchitecture-validate-layer-boundaries - Ensure layers are necessary and well-justifiedquality-code-review - Evaluate abstractions during PR reviewIntegration pattern:
Before:
src/
├── domain/
│ ├── interfaces/user_repository.py
│ ├── interfaces/user_service.py
│ ├── interfaces/user_validator.py
├── application/
│ ├── services/user_service.py (forwards to repo)
│ ├── validators/user_validator.py (just calls validate())
├── infrastructure/
│ ├── repositories/user_repository.py
After (applying minimal-abstractions):
src/
├── domain/
│ ├── repositories.py (UserRepository protocol)
│ ├── models.py (User with validation)
├── application/
│ ├── handlers.py (CreateUserHandler with actual business logic)
├── infrastructure/
│ ├── repositories.py (SqlUserRepository)
Metrics:
Abstraction Evaluation: ProductService
✅ Checklist Results:
❌ Does abstraction already exist? YES - Repository pattern exists
❌ 2+ implementations? NO - Only one service planned
❌ Concrete requirement? NO - "We might need microservices later"
⚠️ Complexity cost: +3 files, +200 LOC, +2 layers indirection
✅ Simpler solution exists? YES - Use repository + handler directly
Recommendation: SKIP THIS ABSTRACTION
- Use existing ProductRepository
- Add business logic to ProductHandler
- Wait for concrete multi-service requirement before abstracting
Key Principle: Every abstraction must justify its existence with concrete, current requirements - not hypothetical future needs.
Balance: This skill advocates for minimal abstractions, but respects architectural patterns when they provide real value (e.g., Clean Architecture's dependency inversion).
When in doubt: Start simple. Add abstractions when pain points emerge, not before.
xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience