Domain Primitives And Always-Valid Models
Make illegal states unrepresentable when the domain rule is stable enough to deserve a type.
Workflow
Identify primitives that carry domain meaning or repeated validation.
Separate syntax checks from domain invariants.
Add a domain primitive with a private constructor and smart constructor or parser.
Store only valid values inside entities and aggregates.
Keep formatting, localization, and transport parsing outside the core type unless they are domain rules.
Use A Domain Primitive When
The value has a domain name.
Validation appears in multiple places.
Mixing two values of the same primitive type would be dangerous.
Behavior belongs with the value.
Avoid Wrapping When
The value is purely technical, temporary, or has no invariant.
A wrapper would add ceremony without changing correctness.
Detailed Reference
For non-trivial implementation, review, or refactoring work, read references/details.md before giving final guidance. It contains the detailed rules, examples, smells, and migration notes that do not belong in the short invocation body.
Output
Return the primitive candidates, chosen wrappers, construction API, error type, and migration steps.