This skill should be used when designing, planning, implementing, or reviewing any non-trivial change, or when the user asks to "generalize this", "extract shared util", "deduplicate this" — enforces DRY, well-defined abstractions, and composable components so code is written once and used many times
Scanned 5/27/2026
Install via CLI
openskills install alo-exp/silver-bullet---
name: reusability
description: This skill should be used when designing, planning, implementing, or reviewing any non-trivial change, or when the user asks to "generalize this", "extract shared util", "deduplicate this" — enforces DRY, well-defined abstractions, and composable components so code is written once and used many times
user-invocable: false
version: 0.1.0
---
# /reusability — Reusable Design Enforcement
Every design, plan, and implementation MUST produce components that are written once and reused everywhere applicable. Duplication is a bug — not in logic, but in design.
**Why this matters:** Duplicated logic drifts over time. When the same concept lives in two places, one gets updated and the other doesn't — causing subtle bugs that are hard to trace. Reusable design prevents this by ensuring every concept has exactly one authoritative implementation.
**When to invoke:** During PLANNING (after `/gsd:discuss-phase`, before `/gsd:plan-phase`) and during REVIEW (as part of code review criteria). This skill applies to both new code and modifications to existing code.
---
## The Rules
### Rule 1: Single Source of Truth
Every piece of knowledge — business rule, algorithm, configuration value, validation logic — MUST have exactly ONE authoritative representation in the system.
| Violation | Fix |
|-----------|-----|
| Same validation in frontend and backend | Shared schema (JSON Schema, Zod, Protobuf) or single validation layer |
| Same constant in multiple files | Extract to a shared constants module |
| Same SQL query in multiple handlers | Extract to a repository/query module |
| Same error message in multiple places | Extract to an error catalog |
**Test:** Search the codebase for the concept. If it appears in more than one place with substantively identical logic, it violates this rule.
### Rule 2: Compose, Don't Inherit
Prefer composition over inheritance for code reuse. Inheritance creates tight coupling between parent and child — changes to the parent ripple unpredictably.
- Build small, focused functions that do one thing well.
- Combine them via composition (pipes, higher-order functions, middleware chains).
- Use inheritance ONLY for true "is-a" relationships with stable base classes.
- If a base class changes more than once per quarter, it's not stable enough for inheritance.
### Rule 3: Design for Consumers
Before writing a reusable component:
1. **Define the API from the consumer's perspective** — what do they need to pass in, and what do they get back?
2. **Minimize required parameters** — sensible defaults for everything non-essential.
3. **Return predictable types** — no union types that force consumers to check "which kind" they got.
4. **Make the common case easy** — if 80% of callers use the same options, make those the defaults.
If you can't explain how to use it in 3 lines of code, it's too complex for reuse — simplify.
### Rule 4: Appropriate Abstraction Level
Not everything should be reused. Premature abstraction is worse than duplication.
| Count | Action |
|-------|--------|
| 1 occurrence | Just write it inline. No abstraction. |
| 2 occurrences | Note the duplication. Consider extracting if the logic is identical. |
| 3+ occurrences | Extract to a shared module. The pattern is confirmed. |
**The Rule of Three:** Wait for the third occurrence before extracting. Two similar things might diverge; three similar things are a pattern.
### Rule 5: Parameterize, Don't Fork
When a variation of existing behavior is needed:
- **DO** add a parameter or configuration option to the existing component.
- **DO NOT** copy the component and modify the copy.
- **DO NOT** create a parallel implementation with slight differences.
If the variation is too different to parameterize cleanly (>30% different logic paths), it's a new component — not a variant.
### Rule 6: Package Boundaries
Reusable code must live at the right level:
| Scope | Location | Example |
|-------|----------|---------|
| Within a feature | Feature's `shared/` or `utils/` | Feature-specific helpers |
| Across features | Project-level `lib/` or `shared/` | Common business logic |
| Across projects | Published package/library | Generic utilities, SDK clients |
Never import from another feature's internals. If two features need the same thing, extract it to a shared location.
### Rule 7: Documentation for Reuse
Every reusable component MUST have:
- **Purpose** — one sentence explaining what it does and when to use it.
- **Interface** — parameters, return types, side effects.
- **Example** — at least one usage example showing the common case.
If it's not documented, it won't be reused — it will be reimplemented.
---
## Applying This Skill
### During Planning (/gsd:discuss-phase → /gsd:plan-phase)
Before finalizing any design or plan, run the **Reusability Checklist**:
- [ ] No planned component duplicates logic that already exists in the codebase
- [ ] Every shared concept has exactly one authoritative implementation
- [ ] Composition is preferred over inheritance for code reuse
- [ ] Reusable components are designed from the consumer's perspective
- [ ] No premature abstraction — only extract at 3+ occurrences (or obvious patterns)
- [ ] Package boundaries are respected — no cross-feature internal imports
- [ ] Every reusable component has purpose, interface, and example documentation
If any item fails: **redesign before proceeding to implementation.**
### During Implementation (/gsd:execute-phase)
As you write code:
- Before writing new logic, search for existing implementations of the same concept.
- If you find duplication at 3+ sites, extract before adding a 4th.
- If you're copying a function to modify it slightly, parameterize instead.
- Every new shared module gets a JSDoc/docstring with purpose, params, and example.
### During Review (code-review / receiving-code-review)
Verify these as part of every code review:
- No new duplication of existing logic
- Reusable components have clear, documented APIs
- No cross-feature internal imports
- Composition over inheritance where applicable
- Appropriate abstraction level (not premature, not overdue)
### When Modifying Existing Code
If existing code violates these rules:
- Not required to fix duplication in unrelated files.
- Required: do not introduce new duplication.
- If you're adding a 3rd+ copy of logic, extract to shared first.
- If modifying a duplicated section, consider unifying as part of the change.
---
## Anti-Patterns
| Pattern | Problem | Fix |
|---------|---------|-----|
| Copy-paste programming | Drift between copies, bugs fixed in one not others | Extract shared component |
| God utility file | Grabs bag of unrelated functions | Split by domain |
| Premature abstraction | Abstraction for 1 use case, overly generic | Wait for Rule of Three |
| Leaky abstraction | Consumer must know internals to use correctly | Redesign the interface |
| Not-invented-here | Rewriting what a dependency already provides | Use the dependency |
| Over-parameterization | 15 options where 3 suffice | Separate components for distinct use cases |
---
## Rationalization Prevention
| Excuse | Reality |
|--------|---------|
| "It's faster to just copy it" | Faster now, 10x slower to debug drift later. |
| "They're almost the same but slightly different" | Parameterize the difference. |
| "I'll consolidate later" | You won't. Extract now. |
| "This is too specific to reuse" | If it exists 3+ times, it's not specific. |
| "Adding parameters makes it complex" | Complex is better than duplicated. |
| "The other team owns that code" | Extract to shared, or coordinate. Don't duplicate. |
No comments yet. Be the first to comment!