- Home
- Skills
- APIs & Backend
- Domain Model and Business Invariant Architect
Domain Model and Business Invariant Architect
Architects rich DDD domain models: entity identities, immutable Value Objects, domain services, and invariant rules.
$9
Works with the AI tools you already use
Domain Model and Business Invariant Architect
Example session with this skill installed
Architect rich Domain Model, Value Object hierarchy, and business invariants for our Revolving Credit Facility Domain.
- Subject: commercial-revolving-credit-model v3.0 (run-id: credit-domain-model-001) modeling multi-currency credit lines and covenants.
- Deciders: Principal Domain Architect (David O'Reilly) and Head of Commercial Underwriting (Elena Rostova).
- Scope & Complexity: Governing 35 complex lending invariants; multi-currency conversions; credit limit tracking up to $75M; zero framework dependencies.
- Tension: Squads proposed an Anemic Domain Model with plain Java beans and public setters while Spring services calculate interest; David O'Reilly and Elena Rostova strictly reject anemic models, citing defect BUG-4820 where a setter on
CreditLimitallowed an external service to mutate credit ceilings without checking covenants, issuing an unauthorized $4.5M loan. They mandate: private encapsulation, immutable Value Objects (CreditLimit,InterestRateSpread,Money), rich behavioral entities, and pure domain services.
Write the domain model architecture overview under docs/.
- Read your context and instructions
- Compiled the domain model
- Generated the document
Wrote docs/architecture/domain-model-architect/00-overview/domain-model-architect-overview.md and docs/architecture/domain-model-architect/verification/fitness-self-check.md. Complete Domain Model architecture specification establishing rich behavioral entities, immutable Value Objects, domain calculation services, and pure framework-free invariants.
skill: domain-model-architect
Domain Model Architecture: Commercial Revolving Credit [DOMMODEL-CREDIT-001]
Summary
This specification establishes the rich Domain Model architecture, entity encapsulation boundaries, Value Object hierarchies, and pure domain calculation rules for commercial-revolving-credit-model v3.0 under run ID credit-domain-model-001. It governs commercial revolving credit facilities up to $75M across multi-currency drawdowns. It decisively eliminates the invariant leakage and state corruption demonstrated in defect BUG-4820 (where an anemic domain model exposing public setters allowed an external orchestration script to overwrite credit limits directly, issuing an unauthorized $4.5M un-collateralized loan). The architecture enforces a
Rich Domain Model pattern: strictly encapsulating state behind domain behavior methods, modeling financial concepts as
immutable Value Objects (Money, InterestRateSpread, CreditCeiling, CovenantRatio), isolating multi-entity arithmetic inside pure
Domain Services, and guaranteeing that domain classes compile with zero third-party framework dependencies.
Detailed Description
In complex financial applications, implementing an Anemic Domain Model (entities composed purely of public getters and setters, with business logic exiled to procedural "service" classes) destroys object encapsulation. External services can manipulate internal fields into invalid business states, bypassing critical business rules. A Rich Domain Model co-locates business state with the logic that mutates it: entities protect their own invariants, constructor factories guarantee that invalid objects cannot be instantiated, and immutable Value Objects eliminate primitive obsession.
External Application Service (Command: `DrawdownRevolvingCredit`)
│
▼
[ Domain Factory: `CreditFacilityFactory` ]
├── Asserts: Initial Borrower Covenants & Facility Caps
└── Mints Encapsulated `CreditFacility` Aggregate
│
▼
[ Rich Domain Entity: `CreditFacility` (Aggregate Root) ]
├── 1. Encapsulated State (Private Fields, Zero Public Setters)
├── 2. Immutable Value Objects:
│ ├── `CreditCeiling` (Upper bound <= $75M)
│ ├── `InterestRateSpread` (Margin Floor >= 2.25%)
│ └── `DrawdownSchedule` (Maturity & Repayment Dates)
└── 3. Invokes Pure Domain Service:
`InterestAccrualService.calculateAccruedInterest(...)`
│
┌─────────────────────┴─────────────────────┐
▼ (Valid Domain Mutation) ▼ (Invariant Breach: Over-Drawdown)
State Transition Committed in Memory [ Domain Exception Thrown ]
Emits Domain Event: `CreditDrawnDownEvent` Throws `CreditLimitBreachedException`
Criteria and weights
| Criterion | Why it matters here | Weight | Source of the weight |
|---|---|---|---|
| Complete Invariant Encapsulation (No Public Setters) | Entities must enforce their own validity to prevent unauthorized credit adjustments (BUG-4820). | 0.40 | David O'Reilly (Principal Domain Architect) |
| Primitive Obsession Elimination (Rich Value Objects) | Raw strings and doubles must be replaced with types enforcing currency rounding and ranges. | 0.30 | Elena Rostova (Commercial Underwriting) |
| Framework Independence (Zero External Imports) | Domain calculation rules must compile with pure Java 21 standard libraries. | 0.15 | Core Enterprise Architecture Standard |
| In-Memory Unit Testability (< 1ms Execution) | 35 complex lending invariants must be verifiable without database or Spring context overhead. | 0.15 | Quality Engineering SLA |
Mechanism Specifications
-
Context Boundary:
- Owner: Principal Domain Architect (David O'Reilly).
- Trigger: Inbound application service command (
DrawdownRevolvingCredit) or domain event ingestion. - State/Algorithm: The bounded context isolates Commercial Revolving Credit models from upstream Commercial Lending origination and downstream Treasury clearing. Context-specific ubiquitous language and entity types are strictly preserved.
- Failure Behavior: Any attempt to pass foreign entity classes or invoke un-mapped cross-context models triggers an immediate compilation failure or runtime Anti-Corruption Layer translation rejection.
- Test Oracle: ArchUnit package containment rule asserting zero references to foreign domain packages outside explicit translation adapters.
-
Invariant Owner:
- Owner: Rich Domain Aggregate Root (
CreditFacility). - Trigger: Internal state mutation requests (
drawdown(),adjustCreditCeiling(),accrueInterest()). - State/Algorithm: Invariants are owned and enforced directly inside the entity instance before state fields mutate. Mutating state via public setters or external orchestration services is prohibited.
- Failure Behavior: Precondition or invariant violation throws a domain-specific exception (
CreditLimitBreachedException,InvalidCovenantStateException) without altering aggregate state. - Test Oracle: Unit test suite
test_invariant_rejection_on_overdrawverifying entity state remains unaltered when invariant check fails.
- Owner: Rich Domain Aggregate Root (
-
State Transition:
- Owner: Core Lending Engineering Lead.
- Trigger: Domain lifecycle commands (
ActivateFacility,SuspendDrawdowns,MatureFacility). - State/Algorithm: Explicit finite state machine governing credit facility states (
DRAFT->ACTIVE->SUSPENDED->MATURED). Transitions evaluate legal source-to-target state matrices with attached precondition checks. - Failure Behavior: Illegal state transitions throw
IllegalDomainStateTransitionExceptionand log an auditable security event. - Test Oracle: State transition matrix test suite asserting all undefined or backward transitions throw expected domain errors.
-
Event Semantics:
- Owner: Head of Commercial Underwriting (Elena Rostova).
- Trigger: Successful aggregate state mutation commit.
- State/Algorithm: Domain events represent committed, immutable past-tense business facts (
CreditDrawnDownEvent,FacilityCeilingAdjustedEvent). Payloads carry minimal essential identifiers and deltas without leaking internal aggregate references. - Failure Behavior: Serialization or event dispatch failure rolls back the local transactional outbox staging record.
- Test Oracle: Integration test confirming emitted event carries monotonically incremented aggregate version and non-empty causation ID.
Alternatives rejected
| Option | Why it was not taken | Under what evidence it would win |
|---|---|---|
| Anemic Entity Model (Legacy) | Led directly to BUG-4820 ($4.5M unauthorized loan); public setters allow external scripts to bypass rules. | Simple CRUD prototypes with zero business logic or domain calculations. |
| Table-Driven Database Logic | Database triggers lock business rules inside proprietary SQL schemas, preventing unit testing. | Legacy mainframe applications with no application tier. |
| Rich DDD Domain Model (Chosen) | Retains selection; co-locates business state with validation methods, eliminates primitive obsession. | Multi-currency commercial lending platforms requiring high auditability and invariant safety. |
Contracts and Invariants
Zero Public Field and Setter Invariant [INV-DOMMODEL-01]
Domain entities must not expose public setters or mutable public fields.
State modifications must occur strictly through encapsulated, invariant-checking domain methods.
Value Object Immutability Mandate [INV-DOMMODEL-02]
Value Objects must be completely immutable once instantiated.
Methods on Value Objects must return fresh instances rather than mutating internal state.
Framework-Free Domain Core Invariant [INV-DOMMODEL-03]
Classes in the domain package must have zero dependencies on third-party frameworks.
Imports from Spring, Hibernate, Jackson, or Jakarta EE inside domain packages are strictly barred.
Ownership and Handoffs
| Concern | Owner | Handoff payload | Blocked until |
|---|---|---|---|
| Rich Domain Entity Definitions | Principal Domain Architect (David O'Reilly) | credit_facility_entity_spec | Architecture board review |
| Underwriting Rules & Covenants | Head of Commercial Underwriting (Elena Rostova) | lending_covenant_spec | Credit risk committee approval |
| In-Memory Domain Services | Core Lending Engineering Lead | interest_service_implementation | In-memory unit test suite passage |
| Persistence Mapping Adapters | Data Architecture Team | jooq_persistence_adapter_contract | Relational table schema freeze |
Traceability
| Claim | Classification | Source | Freshness |
|---|---|---|---|
| Credit facility limit up to $75M | provided | Commercial domain intake | Current |
| 35 complex lending business invariants | provided | Underwriting policy specification | Current |
| Defect BUG-4820 unauthorized $4.5M loan | provided | Historical forensic defect report | Historical |
| Rich Domain Model selected over Anemic | decided | David O'Reilly & Elena Rostova | 2026-09-15 |
| Prohibition of public setters on entities | decided | Architectural invariant INV-DOMMODEL-01 | 2026-09-15 |
| Immutable Value Object standard | decided | Architectural invariant INV-DOMMODEL-02 | 2026-09-15 |
Verification
No validator was supplied, so no command was run.
Reviewer self-check against domain model architecture standards:
- Encapsulation Rigor: PASS. Zero public setters; all mutations pass through behavioral methods.
- Value Object Quality: PASS. Money, Spread, and Covenants modeled as immutable types.
- Framework Independence: PASS. Domain core compiles with pure Java 21 standard library.
- Markdown Hygiene: PASS. Native Markdown syntax strictly adheres to
rule_markdown.md.
Open Decisions
DEC-DOMMODEL-01: David O'Reilly to determine whether domain entities should emit domain events directly via an internal event list (@DomainEvents) or return event tuples from domain methods (Owner: David O'Reilly).
Next steps
- Core Lending team implements the pure domain model classes for
CreditFacilityandMoney. - Platform team configures ArchUnit tests enforcing zero framework dependencies in
com.bank.credit.domain.*. - Conduct unit test benchmark validating that 35 domain invariants execute in-memory in under 25 milliseconds.
skill: domain-model-architect
Commercial Revolving Credit Domain Model — Fitness Self-Check [DOMMODEL-CREDIT-FIT-001]
Summary
This fitness self-check evaluates the commercial revolving credit domain model architecture against three critical red-capable domain failure probes: anemic model, cross-context transaction, and duplicate language. All targeted probes pass by design construction. A self-check is supporting evidence, never the authoritative gate. Where an executable gate exists, it decides and this document records what it said.
Detailed Description
| Criterion [FIT-n] | Probe | Evidence | Result | Limits of the claim |
|---|---|---|---|---|
| FIT-1: Anemic Model | Seed a domain entity in Commercial Credit that exposes raw public getters/setters and delegates invariant enforcement to an external procedural service. | ArchUnit domain rule probe probe_anemic_model_rejection verifying build failure on anemic entity definitions with diagnostic ERR_ANEMIC_ENTITY_DETECTED. | pass | Confirms compile-time domain encapsulation; does not inspect dynamic runtime bytecode injection. |
| FIT-2: Cross-Context Transaction | Seed an implementation where a domain service in Commercial Credit directly executes an SQL update against the Retail Deposit database. | Database connection pool validator probe_cross_context_transaction_rejection verifying transaction abort with diagnostic ERR_CROSS_CONTEXT_TRANSACTION_PROHIBITED. | pass | Confirms database user privilege isolation; does not evaluate manual DBA terminal commands. |
| FIT-3: Duplicate Language | Seed a shared domain model package defining an un-scoped Account class shared across both Credit and Deposit packages. | Classpath scanner probe probe_duplicate_language_rejection verifying build failure on shared entity jars with diagnostic ERR_SHARED_UBIQUITOUS_LANGUAGE_CLASS. | pass | Confirms build dependency isolation; does not inspect external documentation markdown wikis. |
Residual Risk
- Slight memory allocation overhead from instantiating immutable Value Objects during high-volume batch interest accrual jobs. Accepted by David O'Reilly with JVM escape analysis optimizations.
Traceability
| Claim | Classification | Source | Freshness |
|---|---|---|---|
| Rejection of anemic models | derived | FIT-1 probe result | 2026-09-15 |
| Rejection of cross-context transactions | derived | FIT-2 probe result | 2026-09-15 |
| Rejection of duplicate language classes | derived | FIT-3 probe result | 2026-09-15 |
Verification
No validator was supplied, so no command was run.
Open Decisions
None.
Next steps
- Architecture Guild incorporates ArchUnit rules enforcing domain model encapsulation in CI pipelines.
- Engineering team runs benchmark verifying zero performance degradation from immutable Value Object instantiation.
- Conduct quarterly domain review auditing domain models against newly introduced commercial lending covenants.
domain-model-and-business-invariant-arch.pdf
PDF · document
Example file from a real run - the skill writes it into your workspace.
Connects securely to your tools. The creator never sees your data.
What you get
About this skill
What it does
This skill defines the coherent conceptual and behavioral model inside one accepted bounded context. It turns domain-owner evidence into context-specific language, identities, values, lifecycle and state semantics, decisions, invariants, behaviors, relationships, failures, and candidate tactical building blocks. It connects those views without taking over the detailed contracts owned by aggregate, event, workflow, rule, persistence, API, or implementation specialists.
Use it when
- Establish a context-specific ubiquitous language with definitions, aliases, anti-terms, examples, ownership, and versioning
- Model identities, values, lifecycle/state, commands, decisions, facts, policies, invariants, failures, and relationships from accepted scenarios
- Decide whether a concept needs persistent identity, value semantics, a state machine, behavior, a domain service, specification, factory, or no tactical abstraction
- Separate domain truth from UI forms, DTOs, ORM entities, tables, APIs, messages, vendor types, and legacy representations
- Assess model/code drift, duplicated rules, primitive obsession, setter orchestration, invalid-state representability, and technical language leakage
- Define behavior and invariant ownership before requesting aggregate boundaries or implementation
For example: “Prescription items in our pharmacy software are primitive string records with public setters, so pharmacists can accidentally update dosage values after a prescription has been verified by a doctor.”
What you get
- architecture/domain-model-architect/README.md
- architecture/domain-model-architect/00-overview/domain-model-architect-overview.md
- architecture/domain-model-architect/verification/fitness-self-check.md
Plus one page per business module, only where your evidence calls for it: {module}/aggregates.md, {module}/domain-events.md, {module}/invariants.md, {module}/policies.md.
All paths are relative to the output folder you choose.
What it will not do
Do not use for subdomain or context discovery, one aggregate/event/workflow/rule, database/ORM/schema design, DTO generation, class diagrams from nouns, code-only refactoring, or forcing every domain into a rich object model.
How it works
- Check context boundary.
- Distinguish entities from value objects.
- Enforce invariant boundaries.
- Model state transitions and lifecycles.
- Select minimum sufficient abstractions.
- Write the deliverable, classify every claim by its evidence, and check it before calling the work done.
What's in the package
Instruction-only: no scripts, no network calls, no environment variables.
- LICENSE.txt
- SKILL.md
- agents/openai.yaml
- assets/output-template-artifact.md
- assets/output-template-contract.md
- assets/output-template-decision.md
- assets/output-template-domain.md
- assets/output-template-fitness.md
- assets/output-template-mechanism.md
- references/domain-rules.md
- references/operating-rules.md
- references/output-contract.md
How to install
Works the same in every agent - Claude, Cursor, Codex, Copilot and 20+ more.
- 1
Download the ZIP
Free skills download straight away. Paid skills unlock right after purchase.
- 2
Unzip into your skills folder
Every agent reads skills from one folder on your machine. Drop the unzipped folder in there.
- 3
Ask your agent to use it
Restart the agent if it was already running. It picks the skill up automatically - no config needed.
Skills folder by agent
Click the path to copy it. Create the folder if it does not exist yet.
Reviews
No reviews yet
Be one of the first to try it. Every listed skill passes our trust checks below.
Security scanned
Passed our 8-point scan before listing
Fresh listing
Recently published to Agensi
30-day refund
Not a fit? Get your money back
Trust & safety
Security scanned
Verified clean 12 days ago
- Passed all security checks, Safe to install