
M09 Domain
Map domain concepts to Rust entities, value objects, aggregates, and repositories with clear ownership and invariants.
Overview
M09 Domain is an agent skill for the Build phase that guides domain-driven modeling in Rust—entities, value objects, aggregates, and repositories with ownership-aware patterns.
Install
npx skills add https://github.com/actionbook/rust-skills --skill m09-domainWhat is this skill?
- Domain concept to Rust pattern table: Entity, Value Object, Aggregate Root, Repository, Domain Event, Service
- Thinking prompts for identity, invariants, and ownership before defining types
- Guidance on private fields, validated constructors, and type-state for transition rules
- Ownership implications: owned children, Arc/Rc sharing, weak references in aggregates
- Layer 2 design choices framing for DDD in Rust codebases
- Six-row domain concept to Rust pattern mapping table
Adoption & trust: 944 installs on skills.sh; 1.2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are modeling business concepts in Rust but mix entities and DTOs, break invariants, and blur aggregate boundaries.
Who is it for?
Solo builders or small teams shipping Rust APIs or services that need explicit DDD structure before persistence wiring.
Skip if: Quick scripts with no domain rules, or frontends where Rust domain modeling is irrelevant.
When should I use this skill?
CRITICAL: domain model, DDD, entity, value object, aggregate, repository pattern, business rules, validation, invariant.
What do I get? / Deliverables
You classify each concept, choose Rust patterns with correct ownership, and place validation and transitions where the domain layer can enforce rules.
- Entity and value object structs with validated constructors
- Aggregate boundaries and repository trait sketches
Recommended Skills
Journey fit
How it compares
Use for design-layer DDD in Rust, not as a database migration or ORM-specific integration skill.
Common Questions / FAQ
Who is m09-domain for?
Rust developers and agent-assisted builders modeling business domains with entities, aggregates, and repository traits who want DDD-aligned types.
When should I use m09-domain?
During Build backend work when defining domain models, aggregate boundaries, invariants, or mapping DDD terminology to Rust structs and traits.
Is m09-domain safe to install?
Review the Security Audits panel on this Prism page; the skill is design guidance with user-invocable false and no tool permissions listed.
SKILL.md
READMESKILL.md - M09 Domain
# Domain Modeling > **Layer 2: Design Choices** ## Core Question **What is this concept's role in the domain?** Before modeling in code, understand: - Is it an Entity (identity matters) or Value Object (interchangeable)? - What invariants must be maintained? - Where are the aggregate boundaries? --- ## Domain Concept → Rust Pattern | Domain Concept | Rust Pattern | Ownership Implication | |----------------|--------------|----------------------| | Entity | struct + Id | Owned, unique identity | | Value Object | struct + Clone/Copy | Shareable, immutable | | Aggregate Root | struct owns children | Clear ownership tree | | Repository | trait | Abstracts persistence | | Domain Event | enum | Captures state changes | | Service | impl block / free fn | Stateless operations | --- ## Thinking Prompt Before creating a domain type: 1. **What's the concept's identity?** - Needs unique identity → Entity (Id field) - Interchangeable by value → Value Object (Clone/Copy) 2. **What invariants must hold?** - Always valid → private fields + validated constructor - Transition rules → type state pattern 3. **Who owns this data?** - Single owner (parent) → owned field - Shared reference → Arc/Rc - Weak reference → Weak --- ## Trace Up ↑ To domain constraints (Layer 3): ``` "How should I model a Transaction?" ↑ Ask: What domain rules govern transactions? ↑ Check: domain-fintech (audit, precision requirements) ↑ Check: Business stakeholders (what invariants?) ``` | Design Question | Trace To | Ask | |-----------------|----------|-----| | Entity vs Value Object | domain-* | What makes two instances "the same"? | | Aggregate boundaries | domain-* | What must be consistent together? | | Validation rules | domain-* | What business rules apply? | --- ## Trace Down ↓ To implementation (Layer 1): ``` "Model as Entity" ↓ m01-ownership: Owned, unique ↓ m05-type-driven: Newtype for Id "Model as Value Object" ↓ m01-ownership: Clone/Copy OK ↓ m05-type-driven: Validate at construction "Model as Aggregate" ↓ m01-ownership: Parent owns children ↓ m02-resource: Consider Rc for shared within aggregate ``` --- ## Quick Reference | DDD Concept | Rust Pattern | Example | |-------------|--------------|---------| | Value Object | Newtype | `struct Email(String);` | | Entity | Struct + ID | `struct User { id: UserId, ... }` | | Aggregate | Module boundary | `mod order { ... }` | | Repository | Trait | `trait UserRepo { fn find(...) }` | | Domain Event | Enum | `enum OrderEvent { Created, ... }` | ## Pattern Templates ### Value Object ```rust struct Email(String); impl Email { pub fn new(s: &str) -> Result<Self, ValidationError> { validate_email(s)?; Ok(Self(s.to_string())) } } ``` ### Entity ```rust struct UserId(Uuid); struct User { id: UserId, email: Email, // ... other fields } impl PartialEq for User { fn eq(&self, other: &Self) -> bool { self.id == other.id // Identity equality } } ``` ### Aggregate ```rust mod order { pub struct Order { id: OrderId, items: Vec<OrderItem>, // Owned children // ... } impl Order { pub fn add_item(&mut self, item: OrderItem) { // Enforce aggregate invariants } } } ``` --- ## Common Mistakes | Mistake | Why Wrong | Better | |---------|-----------|--------| | Primitive obsession | No type safety | Newtype wrappers | | Public fields with invariants | Invariants violated | Private + accessor | | Leaked aggregate internals | Broken encapsulation | Methods on root | | String for semantic types | No validation | Validated newtype | --- ## Related Skills | When | See | |