From silver-bullet
Enforces open-closed design, plugin architectures, and stable interfaces so systems grow without breaking existing consumers. Use during planning and code review.
How this agent operates — its isolation, permissions, and tool access model
Agent reference
silver-bullet:agents/codex/extensibility/skillThe summary Claude sees when deciding whether to delegate to this agent
Every design, plan, and implementation MUST allow new functionality to be added without modifying existing code. The system should be open for extension but closed for modification. **Why this matters:** Software that requires modifying core code for every new feature becomes brittle, risky, and slow to evolve. Extensible design lets you add capabilities by writing NEW code — not editing existi...
Every design, plan, and implementation MUST allow new functionality to be added without modifying existing code. The system should be open for extension but closed for modification.
Why this matters: Software that requires modifying core code for every new feature becomes brittle, risky, and slow to evolve. Extensible design lets you add capabilities by writing NEW code — not editing existing, tested, working code. This is the difference between systems that scale with the team and systems that bottleneck at every change.
When to invoke: During PLANNING (after /silver:context, before /silver:plan) and during REVIEW (as part of code review criteria). This skill applies to both new code and modifications to existing code.
Modules MUST be open for extension but closed for modification:
| Closed for modification | Open for extension |
|---|---|
| Core processing pipeline | New processors via registration |
| Validation engine | New validators via interface |
| Authentication system | New auth providers via adapter pattern |
| Report generator | New report formats via strategy pattern |
| Event system | New event handlers via subscription |
The test: Can you add a new [feature type] without editing any existing file? If yes, the design is extensible. If no, find the extension point and create it.
Every system MUST define explicit extension points:
| Pattern | Use when |
|---|---|
| Hooks/Events | Others need to react to your system's actions |
| Plugin interface | Third parties add completely new capabilities |
| Strategy pattern | Multiple algorithms for the same operation |
| Middleware chain | Cross-cutting concerns (logging, auth, caching) |
| Configuration | Behavior changes without code changes |
| Registry pattern | New types registered at startup, discovered at runtime |
Every extension point MUST have:
Public interfaces MUST be stable. Once published, an interface is a promise:
| Rule | Implementation |
|---|---|
| Never remove a public method | Deprecate first, remove in next major version |
| Never change a method's signature | Add a new method with the new signature |
| Never change return types | Use generics or union types for flexibility |
| Never change error types | Add new error types, don't modify existing ones |
| Never change default behavior | New defaults only in major versions |
Interface evolution rules:
Behavior that might change MUST be configurable:
| Hard-coded (inflexible) | Configurable (extensible) |
|---|---|
if (country === 'US') | config.supportedCountries.includes(country) |
const MAX_RETRIES = 3 | config.maxRetries ?? 3 |
sendEmail(...) hard-coded | notificationChannels.forEach(ch => ch.send(...)) |
switch (type) { case 'pdf': ... } | formatters.get(type).render(data) |
Not everything should be configurable. Only extract configuration for values that:
Every public API MUST be versioned from day one:
| Layer | Versioning strategy |
|---|---|
| REST APIs | URL path (/v1/users) or header (Accept: application/vnd.api.v1+json) |
| Libraries/packages | Semantic versioning (MAJOR.MINOR.PATCH) |
| Database schemas | Migration numbering with up/down |
| Configuration files | Version field + migration path |
| Message formats | Schema registry with compatibility checks |
Semantic versioning rules:
New versions MUST work with old clients:
| Principle | Implementation |
|---|---|
| Accept old input formats | Parse both old and new format, normalize internally |
| Return backward-compatible output | Add fields, never remove or rename |
| Support old configuration | Migration on startup, not manual conversion |
| Maintain old endpoints | Deprecation notice, proxy to new version |
| Default to old behavior | New behavior requires explicit opt-in |
Breaking change budget: Maximum 1 breaking change per quarter. Each breaking change needs a migration guide AND an automated migration tool where possible.
Separate the HOW (mechanism) from the WHAT (policy):
| Mechanism (stable) | Policy (changes often) |
|---|---|
| Event dispatch system | Which events trigger which actions |
| Permission checking framework | Permission rules and role definitions |
| Validation engine | Validation rules per entity |
| Notification system | When and how to notify |
| Workflow engine | Workflow step definitions |
The mechanism is the extensible framework. The policy is the configuration/plugins that define behavior. When policy changes (it will), no mechanism code needs to change.
Before finalizing any design or plan, run the Extensibility Checklist:
If any item fails: redesign before proceeding to implementation.
As you write code:
else if.Verify these as part of every code review:
switch or if/else if chains that will grow as new types are addedIf existing code violates these rules:
else if for a new type, convert to a registry/strategy.| Pattern | Problem | Fix |
|---|---|---|
| Giant switch/case for types | Every new type modifies the switch | Registry or strategy pattern |
| Hardcoded providers | Can't swap implementations | Interface + injection |
| Unversioned APIs | Can't evolve without breaking | Version from day one |
| Breaking changes without notice | Consumers break silently | Deprecation cycle |
| God config file | Everything in one place, impossible to extend | Split by concern, compose |
| Feature flags as architecture | Permanent conditionals in code | Plugin/extension points |
| Excuse | Reality |
|---|---|
| "We don't need plugins" | You need the pattern, not necessarily a plugin system. |
| "YAGNI — we don't need to extend this" | If 3+ types exist or are planned, you need an extension point. |
| "Breaking changes are fine, we control all consumers" | You won't forever. And you'll forget who consumes what. |
| "Versioning is overhead" | Versioning is cheap. Breaking consumers is expensive. |
| "We can just update everyone" | At 10 consumers, maybe. At 100, impossible. |
| "This is internal, we can change it" | Internal APIs have consumers too. Treat them with respect. |
npx claudepluginhub alo-exp/silver-bullet --plugin silver-bulletExpert Go code reviewer that analyzes diffs, runs go vet and staticcheck, and checks for idiomatic Go, concurrency bugs, error handling, and security issues.