Skip to content

entities: enforce immutability doctrine across domain models#125

Merged
absoludity merged 5 commits into
masterfrom
119-immutability-doctrine
Mar 25, 2026
Merged

entities: enforce immutability doctrine across domain models#125
absoludity merged 5 commits into
masterfrom
119-immutability-doctrine

Conversation

@absoludity
Copy link
Copy Markdown
Collaborator

Replacement for auto-closed PR #120.

Domain models are records — snapshots of business state — not stateful
objects. Without an explicit contract, mutable collections creep in
(list, dict), direct field assignment happens in use cases and
repositories, and the distinction between "changing an entity" and
"creating a new snapshot" becomes unclear. This matters especially in
Temporal workflows where shared in-memory state across signal handlers
and activity calls is a source of subtle replay bugs.

A new Entity base class in core/entities/entity.py establishes the
contract: frozen=True prevents field reassignment, and doctrine tests
enforce that all domain models inherit from Entity and use only
immutable collection annotations (tuple, Mapping, frozenset).

All ceap and polling domain models now extend Entity. Mutable list/dict
annotations have been replaced with tuple/Mapping. The repository base
classes (memory and minio) previously mutated entity fields directly in
update_timestamps — these now return new instances via model_copy.
Use cases that assigned to entity fields mid-workflow do the same.
@absoludity absoludity merged commit 06273dc into master Mar 25, 2026
7 checks passed
@absoludity absoludity deleted the 119-immutability-doctrine branch March 25, 2026 23:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant