Cohesive.Transitions 0.1.0-alpha.156

This is a prerelease version of Cohesive.Transitions.
dotnet add package Cohesive.Transitions --version 0.1.0-alpha.156
                    
NuGet\Install-Package Cohesive.Transitions -Version 0.1.0-alpha.156
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Cohesive.Transitions" Version="0.1.0-alpha.156" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Cohesive.Transitions" Version="0.1.0-alpha.156" />
                    
Directory.Packages.props
<PackageReference Include="Cohesive.Transitions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Cohesive.Transitions --version 0.1.0-alpha.156
                    
#r "nuget: Cohesive.Transitions, 0.1.0-alpha.156"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Cohesive.Transitions@0.1.0-alpha.156
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Cohesive.Transitions&version=0.1.0-alpha.156&prerelease
                    
Install as a Cake Addin
#tool nuget:?package=Cohesive.Transitions&version=0.1.0-alpha.156&prerelease
                    
Install as a Cake Tool

Cohesive.Transitions

Instance composition

DomainModel offers optional instance authoring over DomainModelBuilder: declare entities in the derived constructor and use inherited Definition. First access freezes the builder and caches the exact immutable entity catalog; late additions fail. No reflection or virtual construction hook is used.

Cohesive.Transitions models one entity change as portable, inspectable semantics: admission rules, branching, sparse updates, invariants, interactions, machine movements, and typed outcomes.

Canonical execution IR declares IImmutableExecutionDefinition, so repeated typed reads share document-owned immutable decoding. Integrity, canonical-wire, contextual semantics, and deployment admission remain independently validated. See immutable execution preparation.

Install

dotnet add package Cohesive.Transitions

Start with an immutable record

Transition expressions can use ordinary POCO properties without inheriting from Entity<T>:

public sealed record RunControl(bool Eligible, string Status);
public sealed record ApproveRun(bool Approved);

At application startup, resolve the entity shape and author the transition:

var entity = ObjectEntityDefinition.For<RunControl>(new("run-control"));
var metadata = new TransitionAuthoringMetadata(
    new("run-control/approve"), new("revision/1"), new("body"),
    new(new(TransitionAuthoring.Producer), new("example/run-control"), DocumentOrigin.Generated));

var approve = TransitionAuthoring.Create<RunControl, ApproveRun, string>(
    entity.Shape,
    metadata,
    transition => transition
        .Invariant(new("valid-status"), state => state.Status != "invalid")
        .Requires(new("eligible"), (state, input) => state.Eligible && input.Approved,
            (state, input) => "rejected")
        .Set(new("approve"), state => state.Status, "approved")
        .Return(new("result"), TransitionOutcomeDisposition.Applied, "approved"));

The shape and the restricted expressions produce the same canonical Transition IR as explicit entities and direct IR authoring. Compile the document once and reuse its plan. Invocation expressions read the original observation; ordered patches produce a candidate observation, and invariants check that candidate. Neither authoring nor execution mutates the record. POCO authoring and execution covers materialization, names, value-object contracts, and the supported subset.

Entity field updates

For a declarative Entity<T> field, both Set(entity => entity.Status, "ready") and Set(entity => entity.Status, (_, input) => input.Status) use the entity-field selector overload. Their step identity is set/Status, independent of authoring order. SetNull(entity => entity.OptionalValue) produces a Set patch containing JSON null; it does not remove the field. Nullable value types are checked by the method's generic constraints; reference fields must also permit null in their semantic contract. Use Remove when absence is intended.

Updating the same field more than once, including in different branches, requires explicit step IDs. Duplicate field-named IDs produce ordinary duplicate-node validation diagnostics. Explicit-ID overloads remain available for every update. POCO short constant updates retain their documented authoring-order identities.

Candidate state and composition

TransitionStateProjector.ApplyToEntity prepares a validated entity candidate from a canonical TransitionDecision. API, service, and process transition consumers share its version and patch-before-value rules. Commit fences and emission ownership remain at their execution boundaries. See entity/transition/process composition for the implemented boundary and the remaining CRUD, history, and reconstitution work.

Explicit entity declarations

The C# entity surface discovers fields and produces the canonical observation shape. Ordinary field declarations do not require node IDs:

public enum LoadStatus { Draft, Assigned }
public sealed class Load : Entity<Load>
{
    public Load()
    {
        Status = Field(nameof(Status), LoadStatus.Draft);
        CarrierId = Field<string?>(
            nameof(CarrierId),
            initialValue: null,
            configure: field => field.Optional());

        Invariant(
            "AssignedLoadsHaveACarrier",
            load => load.Status != LoadStatus.Assigned ||
                    load.CarrierId != null);
    }

    public Field<LoadStatus> Status { get; }

    public Field<string?> CarrierId { get; }
}

Transition authoring then uses restricted typed expressions over the current entity observation and a typed input. Those expressions lower immediately into canonical IR; arbitrary method calls, hidden I/O, captured runtime state, loops, and mutation are rejected.

What a Transition produces

  • A canonical, persistable ExecutionDefinitionDocument.
  • Exact input, entity-observation, and outcome contracts.
  • Admission rules and deterministic branch structure.
  • An algebraic sparse patch rather than in-place entity mutation.
  • Interaction intents and machine movements when declared.
  • Candidate-state invariant checks and typed outcome evidence.
  • Structured source maps, validation diagnostics, and a semantic fingerprint.

The document is the semantic authority. The typed handle, static plan, reference interpreter decision, repository commit, and emitted interaction envelopes are projections or interpretations of that exact document.

Current authoring boundary

Entity shape discovery and common field defaults are convention-driven. The current Transition builder keeps stable identities explicit for durable rules, branches, updates, and outcomes; advanced examples and the canonical IR are therefore documented separately. Additional identity conventions should be added to the authoring API before they are presented as ordinary syntax.

Use it when

  • Entity invariants and legal changes should be explicit and reusable across hosts.
  • A decision must be testable without a database, message broker, or HTTP endpoint.
  • Storage needs a sparse patch and exact concurrency evidence rather than an opaque callback.
  • Processes, APIs, presentation actions, and tooling should reference the same domain behavior.

Continue

  • Internals contains the complete explicit authoring example, canonical IR, persistence, compilation, reference interpretation, and expression-site details.
  • Execution kernel guide explains Transition linking and execution boundaries.
  • Cohesive.Storage attaches repository and commit interpretations.
  • Cohesive.Processes coordinates Transition invocations with other semantic work.

Start a multi-entity domain

DomainModelBuilder.Entity<T>(semanticName) returns a typed DomainEntity<T> retaining the exact definition in the built entity catalog. Declare it once, then attach downstream concerns:

var domain = new DomainModelBuilder().Version("1");
var orders = domain.Entity<Order>("orders");
var reservations = domain.Entity<Reservation>("reservations");
var reservationOrder = reservations.References(reservation => reservation.OrderId, orders);
var definition = domain.Build();

entity.Definition supplies transition/storage authority. entity.QueryShape(author) imports that exact graph into a Relations expression session, avoiding an independently inferred CLR query shape. author.Source(entity) combines that import with source creation when a separate shape handle is unnecessary. References uses an existing Relations relationship definition and names the target observation identity; it does not create a foreign key, establish tenant scope or enforce authorization. The typed handle carries both exact endpoint documents, imported automatically by forward and inverse traversal. Explicit imports remain valid; conflicting session registrations fail closed. A traversal retains the separately declared relationship in its authoring catalog. Entity handles contain no runtime state, persistence or workflow. See the runnable fulfillment example.

Domain entity handles expose entity.Transition<TInput, TOutcome>(id, revision, configure) and entity.Transition<TOutcome>(...) for Unit-input operations. These delegate to TransitionAuthoring.Create with the entity's exact declared shape and caller attribution; no parallel model or invocation-time compilation is introduced. Instance methods retain the entity type without repeating it as a method argument; generic extension receivers cannot partially infer explicit method type arguments here.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (7)

Showing the top 5 NuGet packages that depend on Cohesive.Transitions:

Package Downloads
Cohesive.Processes

Cohesive semantic system definition and orchestration building blocks.

Cohesive.Storage

Cohesive semantic system definition and orchestration building blocks.

Cohesive.Api

Cohesive semantic system definition and orchestration building blocks.

Cohesive.Identity

Cohesive semantic system definition and orchestration building blocks.

Cohesive.Host

Cohesive semantic system definition and orchestration building blocks.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.0-alpha.156 72 10/22/2026
0.1.0-alpha.155 121 10/20/2026
0.1.0-alpha.154 121 10/20/2026
0.1.0-alpha.153 119 10/20/2026
0.1.0-alpha.152 143 10/19/2026
0.1.0-alpha.151 168 10/19/2026
0.1.0-alpha.150 169 10/19/2026
0.1.0-alpha.149 171 10/18/2026
0.1.0-alpha.148 167 10/18/2026
0.1.0-alpha.147 174 10/18/2026
0.1.0-alpha.146 171 10/18/2026
0.1.0-alpha.145 167 10/17/2026
0.1.0-alpha.144 170 10/17/2026
0.1.0-alpha.143 174 10/16/2026
0.1.0-alpha.142 161 10/16/2026
0.1.0-alpha.141 178 10/16/2026
0.1.0-alpha.140 168 10/15/2026
0.1.0-alpha.139 183 10/13/2026
0.1.0-alpha.138 166 10/13/2026
0.1.0-alpha.137 158 10/12/2026
Loading failed