opencode-workflow/skills/system-decomposition/SKILL.md

100 lines
4.0 KiB
Markdown
Raw Normal View History

2026-04-10 09:24:59 +00:00
---
name: system-decomposition
description: "Knowledge contract for splitting systems into services or modules, defining boundaries, data ownership, and dependency direction. Referenced by design-architecture when designing service boundaries."
---
This is a knowledge contract, not a workflow skill. It is referenced by `design-architecture` when the architect is designing service boundaries and system decomposition.
## Core Principles
- Each service or module must have a single, well-defined responsibility
- Data ownership must be clear: each piece of data belongs to exactly one service
- Dependencies must flow in one direction; cyclic dependencies are forbidden
- Boundaries must be drawn around domain responsibilities, not technical layers
## Decomposition Decisions
### Modular Monolith vs Microservices
Choose modular monolith when:
- Team size is small (fewer than 5-8 engineers per service boundary)
- Domain boundaries are still evolving
- Deployment simplicity is a priority
- Inter-service communication overhead would exceed in-process call overhead
- The PRD does not require independent scaling of individual services
Choose microservices when:
- Individual services have different scaling requirements stated in the PRD
- Team ownership aligns with service boundaries
- Domain boundaries are stable and well-understood
- Independent deployment of services is required
- The PRD explicitly requires isolation for reliability or security
Do not choose microservices solely because they are fashionable or because the team might need them someday. YAGNI applies.
### Domain Boundaries
Identify domain boundaries by looking for:
- Entities that change together
- Business rules that are cohesive
- Data that is accessed together
- User workflows that span a consistent context
A good boundary:
- Has high internal cohesion (related logic stays together)
- Has low external coupling (minimal cross-boundary calls)
- Can be understood independently
- Can be deployed independently if needed A bad boundary:
- Requires frequent cross-boundary calls to complete a workflow
- Splits closely related entities across services
- Exists because of technical layering rather than domain logic
- Requires distributed transactions to maintain consistency
### Coupling vs Cohesion
Favor high cohesion within a boundary:
- Related business rules live together
- Related data is owned by the same service
- Related workflows are handled end-to-end
Minimize coupling between boundaries:
- Communicate via well-defined contracts (APIs, events)
- Avoid sharing database tables between services
- Avoid synchronous call chains longer than 2 services deep when possible
- Prefer eventual consistency for cross-boundary state updates
### State Ownership
Each piece of state must have exactly one owner:
- The owning service is the single source of truth
- Other services access that state via the owner's API or events
- No service reads directly from another service's database
- If data is needed in multiple places, replicate via events with a clear source of truth
## Communication Patterns
### Synchronous
- Use when the caller needs an immediate response
- Use for queries and command validation
- Avoid for long-running operations
- Consider timeouts and circuit breakers
### Asynchronous
- Use when the caller does not need an immediate response
- Use for events, notifications, and eventual consistency
- Use when decoupling producer and consumer is valuable
- Consider ordering, retry, and DLQ requirements
### Event-Driven
- Use when multiple consumers need to react to state changes
- Use for cross-boundary consistency (eventual)
- Define event schemas explicitly
- Consider event versioning and backward compatibility
## Anti-Patterns
- Distributed monolith: microservices that must be deployed together
- Shared database: multiple services reading/writing the same tables
- Synchronous chain: 3+ services in a synchronous call chain
- Leaky domain: business rules that require data from other services directly instead of via APIs or events
- Premature decomposition: splitting before boundaries are understood