Cohesive Systems logoCOHESIVE SYSTEMS

Building Blocks

Cohesive.Entities

Cohesive.Entities defines business entities by identity, state, invariants, transitions, effects, and lifecycle semantics.

Core Idea

Business entities are not just records. They carry identity, state, invariants, legal transitions, and effects.

Cohesive.Entities records those facts in the system graph. Runtime objects, database rows, API operations, UI actions, workflow steps, and event streams become realizations of the same entity definition instead of separate versions of business logic.

Why Not Just Use POCOs?

POCOs, records, and ORM entities are excellent representations of structure. Through reflection, attributes, and source generators they can support validation, serialization, schema generation, API generation, and administrative tooling.

Cohesive.Entities records behavior as model data: fields, invariants, transitions, effects, read sets, write sets, and lifecycle rules.

Because those facts are explicit, the compiler and runtime can inspect entity behavior without reverse-engineering method bodies or framework conventions.

What the Model Carries

The entity model carries:

  • Explicit state machines and lifecycle analysis
  • First-class domain events and effects
  • Read/write set analysis
  • Automatic change tracking
  • Transition-level authorization and auditing
  • Observation-based execution without entity hydration
  • Partial state loading and targeted updates
  • Incremental recomputation and projection maintenance
  • Structure-of-arrays (SoA) and columnar memory layouts
  • Runtime optimization and specialized execution strategies
  • Storage and execution model independence
  • Visualization and tooling
  • Workflow and process integration
  • Cross-cutting concerns attached to the model rather than scattered throughout the codebase

Those capabilities come from the model itself, not from separate framework conventions, infrastructure code, or application-specific plumbing. Some are possible with conventional object-oriented models. Others are difficult to recover once behavior exists only as imperative code.

A Semantic Entity Model

Most business entities are constrained stateful systems.

Orders move through fulfillment stages. Shipments move through transportation stages. Tasks move through review and completion stages.

Traditional systems often treat those entities as runtime objects. State is represented as fields, while the rules governing state transitions are distributed across methods, services, controllers, event handlers, workflows, and UI code.

For example, a load can be modeled as a class with local state and a Dispatch method:

public sealed class Load
{
    public string Id { get; init; } = "";
    public string Status { get; private set; } = "Covered";
    public decimal Distance { get; private set; }
 
    public LoadDispatched Dispatch()
    {
        if (Status != "Covered")
        {
            throw new InvalidOperationException(
                "Only covered loads can be dispatched.");
        }
 
        if (Distance <= 0)
        {
            throw new InvalidOperationException(
                "A dispatched load must have a positive distance.");
        }
 
        Status = "Dispatched";
 
        return new LoadDispatched(Id);
    }
}
 
public sealed record LoadDispatched(string LoadId);

That object contains useful behavior, but the behavior is still embedded in imperative code. The runtime can call the method, but it cannot reliably inspect the lifecycle, infer the read set, identify the write set, attach transition-level policy, project the state machine, or reason about emitted effects without understanding the method body.

In Cohesive, the authoring code lowers into a semantic entity definition.

public sealed class LoadEntity : Entity
{
    public LoadEntity()
    {
        Identity(nameof(Load.Id));
 
        Field<string>(nameof(Load.Status))
            .States(
                "Uncovered",
                "Covered",
                "Dispatched",
                "Delivered");
 
        Field<decimal>(nameof(Load.Distance))
            .Invariant(distance => distance >= 0);
 
        Transition("Dispatch")
            .Reads(
                nameof(Load.Status),
                nameof(Load.Distance))
            .Requires(load => load.Status == "Covered")
            .Requires(load => load.Distance > 0)
            .Writes(
                nameof(Load.Status),
                "Dispatched")
            .Emits(load => new LoadDispatched(load.Id));
    }
}

The important difference is not that the model avoids code. It is that the code is authoring syntax for identity, fields, invariants, transitions, state requirements, writes, and effects represented directly in the model.

With that representation, Dispatch is no longer just a method body. It is a permitted state transformation that can be analyzed, visualized, validated, authorized, audited, projected into APIs, connected to workflows, and executed by different runtimes.

A runtime object becomes one possible realization of the definition alongside:

  • Observations
  • Document projections
  • Search indexes
  • Materialized views
  • Event-sourced state
  • Columnar storage
  • Structure-of-arrays layouts

This separation between entity semantics and entity realization is the foundation for the capabilities described below.

Formal State Machines

As entity lifecycles become more complex, transitions naturally form state machines.

Because transitions are explicitly modeled, Cohesive.Entities can integrate with formal state machine representations such as Cohesive.Machines.

That supports:

  • Reachability analysis
  • Dead-state detection
  • Invalid transition detection
  • Permission analysis
  • Workflow visualization
  • Runtime enforcement

Instead of reverse-engineering workflow behavior from application code, the lifecycle becomes part of the model itself.

Effects and External Interaction

Business operations often require interaction with systems outside the entity.

For example:

ChangeStops
  → CalculateDistance
  → CalculateEta

Traditional architectures typically implement this using application services, message handlers, outbox processors, workflow engines, or infrastructure-specific code.

Cohesive.Entities defines effects as part of the transition model, so required interactions can be expressed without coupling business logic to infrastructure.

Effects may represent:

  • Domain events
  • Requests for work
  • Notifications
  • Process signals
  • External service interactions

The runtime determines how effects are realized:

  • Synchronously
  • Asynchronously
  • Through queues
  • Through workflows
  • Through actor systems
  • Through custom infrastructure

Business semantics remain unchanged.

Domain Events as First-Class Concepts

Transitions can emit domain events representing meaningful business facts.

TenderAccepted
LoadCovered
InvoicePaid

These events can be:

  • Persisted
  • Published
  • Projected
  • Audited
  • Consumed by other systems
  • Used to initiate workflows

Because events are tied directly to transitions, they become part of the entity model rather than implementation details hidden within application code.

Read and Write Set Analysis

Every transition interacts with state.

Because fields and transitions are modeled explicitly, runtimes can determine which fields are required and which fields may be modified.

ApproveOrder
 
Reads:
  CreditLimit
  OutstandingBalance
 
Writes:
  Status
  ApprovedAt

That supports:

  • Conflict detection
  • Optimistic concurrency
  • Dependency analysis
  • Incremental recomputation
  • Efficient projection updates
  • Selective state loading

These capabilities are difficult or impossible to infer reliably from arbitrary imperative code.

Execute Transitions Without Hydrating Entities

Traditional domain models typically require entities to be fully reconstituted before business logic can execute.

Storage
  → Hydrate Entity
  → Execute Logic
  → Persist Entity

Because Cohesive.Entities models fields, transitions, and read/write sets explicitly, runtimes can execute transitions directly against observations containing only the required state.

Transition
  → Read Set
  → Observation
  → Execute
  → Changeset

Instead of hydrating an entire entity, the runtime can:

  • Read only required fields
  • Populate a lightweight observation
  • Execute transition logic
  • Produce a changeset
  • Persist only modified fields

The entity definition remains the source of truth, but a runtime object graph is no longer required.

That supports:

  • Partial entity loading
  • Reduced memory pressure
  • Targeted document updates
  • Efficient SQL generation
  • Incremental processing
  • High-performance execution strategies

First-Class Change Tracking

Because transitions and fields are explicit, the runtime can directly determine:

  • Which fields changed
  • Why they changed
  • Which transition caused the change
  • Which effects were produced

Rather than comparing object graphs after the fact, change tracking becomes a natural consequence of transition execution.

This supports:

  • Auditing
  • Synchronization
  • Event generation
  • Observability
  • Historical analysis

without duplicating business logic.

Alternative Runtime Representations

Traditional entity models are tightly coupled to object-oriented memory layouts.

Cohesive.Entities separates entity semantics from entity realization.

The same entity definition may be realized as:

  • Runtime objects
  • Observations
  • Search documents
  • Materialized views
  • Event streams
  • Columnar storage
  • Structure-of-arrays (SoA) layouts

Runtimes can choose the representation that fits a workload while preserving the same business semantics.

Storage and Execution Independence

Entity definitions are independent of persistence and execution architecture.

The same entity model can be realized using:

  • PostgreSQL and an ORM
  • Cosmos DB and an outbox
  • Event sourcing
  • Actor systems
  • Durable workflows
  • Custom runtimes

Business semantics remain stable while infrastructure evolves.

Cross-Cutting Concerns

Because transitions, effects, fields, and invariants are represented explicitly, concerns that are traditionally scattered throughout the codebase can be attached directly to the entity model.

Examples include:

  • Validation
  • Authorization
  • Auditing
  • Logging
  • Notifications
  • Telemetry
  • Transactions
  • Compensation policies

These concerns become part of the execution model rather than handwritten boilerplate.

Part of the Cohesive System Model

Entities define business state and behavior.

They integrate naturally with other Cohesive building blocks:

  • Shapes define structure
  • Relations define mappings and dependencies
  • Processes coordinate work across entities
  • Presentation projects entities into APIs and user interfaces
  • Infrastructure realizes persistence, messaging, and execution

Together these blocks form the semantic system graph.

A Foundation for Semantic Systems

Cohesive.Entities treats entities as semantic objects with identity, state, behavior, and effects.

Business behavior becomes part of the graph instead of being spread across services, handlers, jobs, UI state, and persistence code. The same entity definition can be realized across databases, messaging systems, workflow engines, APIs, and execution runtimes without making any one representation the source of business semantics.