domain-primitives-and-always-valid

Design immutable domain types with smart constructors to enforce invariants.

81|3|Updated Jan 14, 2026
One-click install
npx skills add https://github.com/j5ik2o/okite-ai --skill domain-primitives-and-always-valid
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: domain-primitives-and-always-valid
Source: https://github.com/j5ik2o/okite-ai/tree/main/.agent/skills/domain-primitives-and-always-valid
Command: npx skills add https://github.com/j5ik2o/okite-ai --skill domain-primitives-and-always-valid

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve?

Domain Primitives & Always-Valid Domain Model remove dependence on raw primitive types by wrapping them in domain-specific, immutable types that enforce invariants at construction. This approach prevents invalid states, improves code readability, and enables stronger compiler-time guarantees. It provides a blueprint for modeling core domain concepts that are safe to compose and reason about.

Core Features & Use Cases

  • Domain Primitives: wrap primitive values to enforce invariants at construction time.
  • Always-Valid: ensure domain objects represent valid states and expose only safe operations.
  • Smart Constructors & Validation: use factory methods to enforce invariants and prevent invalid instances.
  • Range/NonEmpty & composite values: model bounded domains, sequences, and related value types like Money, Age, Email.
  • Language-agnostic guidance: applies to Rust, TypeScript, Java, and other languages for broad applicability.

Quick Start

Define a domain primitive by wrapping a primitive value with a smart constructor that enforces invariants.

Frequently Asked Questions about domain-primitives-and-always-valid

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
What is an always-valid domain model and how does it prevent invalid states?

An always-valid domain model enforces invariants at construction time using domain primitives, ensuring objects can never exist in an invalid state. By wrapping raw primitive types in immutable, domain-specific types, it prevents invalid states and improves code readability.

How do I implement a smart constructor to enforce range constraints and non-empty types?

To implement a smart constructor, define a factory method that validates range constraints and non-empty sequences before instantiating an immutable domain primitive. This ensures only valid values are created, preventing invalid instances throughout the domain layer.

Can I use domain primitives to model values like Money, Age, and Email in TypeScript and Java?

Yes, domain primitives provide language-agnostic guidance to model composite values like Money, Age, and Email. They apply to Rust, TypeScript, Java, and other languages to wrap primitive values and enforce invariants at construction.

What's the best way to refactor raw primitive types into domain-specific immutable types?

The best way to refactor raw primitive types is to wrap them in domain-specific, immutable types using smart constructors. This approach removes dependence on raw primitives, enforces invariants at construction, and enables stronger compiler-time guarantees.

Why should I use domain primitives instead of raw primitive types in my domain layer?

You should use domain primitives instead of raw primitive types to enforce invariants at construction and ensure safety. Wrapping primitives in immutable, domain-specific types removes dependence on raw values, improves code readability, and enables stronger compiler-time guarantees.

Does this approach to domain modeling work for both new feature work and existing code refactoring?

Yes, designing domain-specific, immutable types supports both new feature work and existing code refactoring. It applies to Rust, TypeScript, Java, and other languages to model values safely and support reviews throughout the domain layer.