Cohesive Systems logoCOHESIVE SYSTEMS

Search Cohesive Systems

Ready

Search Cohesive Systems

Find product pages, building blocks, technical articles, and graph definitions.

Cohesive.Transitions Internals

From C# Decision to Execution

How authored Transitions become durable definitions, request only the state they need, and hand accepted decisions to storage and delivery infrastructure.

Why These Internals Exist

The Cohesive.Entities overview presents the application model: an entity owns state and invariants, while a Transition accepts current state and input and returns a business decision.

A production system must carry that decision across several external boundaries. State may come from a database or service. Accepted changes need concurrency protection. Events and requests must become durable before delivery. Definitions need to survive deployment and version changes. Diagnostics need to explain which rule and input produced a result.

Cohesive calls those concerns the Transition's externalities. The internals on this page preserve the business decision while storage, messaging, coordination, and deployment systems realize it.

From Authoring Syntax to a Source of Truth

The typed C# builder is an authoring frontend. Cohesive evaluates that builder once and lowers its expressions into a canonical Transition document. The callback itself is not needed after authoring.

This is the fuller meaning of the source-of-truth statement from the earlier page: the persisted document carries the Transition's semantics after the original C# code has produced it. It can be restored, inspected, validated, and interpreted without treating an entity method, callback, or runtime service as a second implementation of the business rule.

That property becomes useful when definitions cross process, version, or tooling boundaries. It is an architectural capability rather than the application-level reason to start using Entities.

C# authoring code

Role
A typed, familiar way to declare fields, rules, branches, changes, effects, and outcomes.
Lifetime
Runs when the definition is produced; it is not retained as executable Transition behavior.

Canonical Transition document

Role
The normalized and versioned representation of the authored semantics.
Lifetime
Persisted, fingerprinted, linked by other definitions, and restored across runtimes.

Compiled plan

Role
A validated execution artifact with linked requirements and indexed nodes.
Lifetime
Derived from one exact document and recreated when that definition changes.

Transition decision

Role
The outcome, proposed patch, effects, reads, conflicts, diagnostics, and trace for one invocation.
Lifetime
Produced per evaluation and handed to the infrastructure responsible for commit and publication.

The Canonical Model

A Transition document is a finite program over typed input and entity observations. Its closed node model includes lexical values, ordered predicate choices, exact matches, sparse updates, interaction emissions, Machine movements, and terminal outcomes.

typed input and observation
admission and finite control flow
sparse patches and emissions
candidate-state invariants
one typed Transition decision

Sparse updates are algebraic operations rather than an unstructured dictionary. The current model supports setting and removing values, increments, set addition, append, and owned-child upsert or removal. Each operation carries stable identity and a source-map location.

The expression frontend accepts only computation representable by the shared portable expression language. Captured runtime state, arbitrary method calls, loops, reflection, mutation, and hidden I/O fail during authoring instead of becoming opaque runtime behavior.

This restriction is the tradeoff behind the C# syntax. The authored lambdas look familiar, while their supported semantics remain closed enough to validate, serialize, and interpret consistently.

One Transition Lifecycle

Canonical Transition lifecycle

Typed C# authoring or imported definition, then Canonical execution-definition document, then Validated compiled plan, then Non-committing Transition decision, then Capability-checked commit and publication

C# is the authoring surface. Each later stage remains attributable to the exact definition that established the decision.

Display text and source locations remain useful attribution metadata, but they do not change the semantic fingerprint. A source file can move without changing the Transition's meaning; changing a rule, patch, effect, or outcome produces a different semantic artifact.

Sparse Observation and Path-Level Reads

The compiler identifies the state a Transition might need. Interpretation records the fields the selected path did read. The distinction matters when one branch depends on several fields and another can decide from only one.

A sparse observation preserves semantic absence. No entry means the path was not observed. An entry may explicitly contain Absent, Null, Unknown, Failed, or a concrete value. An adapter cannot collapse these cases without changing the decision's meaning.

Path-level reads let an adapter acquire only relevant state, issue targeted updates, and perform precise concurrency checks without requiring every runtime to hydrate a mutable object graph.

A Decision Comes Before Commit

TransitionReferenceInterpreter is deterministic and non-committing. It invokes no service or delegate, performs no I/O, and mutates no caller-owned state.

The result distinguishes accepted change, accepted no-change, admission rejection, authored domain rejection, concurrency conflict, invalid definition, and infrastructure failure. When a commit is required, the decision also states which actual observations must remain coherent and whether patches and emissions require atomic persistence.

Fresh commit observations can be supplied for conflict validation. A changed actual read produces exact expected-versus-observed evidence. Missing fresh evidence fails closed when the requested interpretation depends on it.

The external commit layer remains responsible for mapping semantic fields to physical storage, choosing a concurrency mechanism, opening a transaction, applying the patch, and recording durable outgoing work. None of those choices changes what the Transition decided.

Interaction Emissions

An effect begins as a pure emission intent that references one exact interaction contract. The referenced contract determines whether the interaction is a domain event or a request, as well as its payload and response obligations.

After the state decision is accepted, infrastructure lowers those intents into canonical envelopes with stable logical emission identity, origin, correlation, typed payload, and target evidence. The Storage-owned Process integration can commit a Transition operation receipt and the resulting envelopes into the Process outbox as one durable successor.

This keeps the transactional outbox boundary explicit. A Transition describes what must be emitted. Storage and delivery adapters prove how the emission becomes durable and publishable.

Lifecycle structure belongs to an authoritative state machine. A Transition that moves a Machine persists an exact Machine reference and edge identity instead of copying the lifecycle graph into its own body.

Compilation links the referenced edge and pins its source predicate, target predicate, and assignments into the plan. Interpretation verifies the source configuration, applies edge-owned assignments to candidate state, and checks the target configuration.

The split lets an entity expose a named business operation while a Machine remains authoritative for lifecycle topology and legal movement.

Identity, Provenance, and Compatibility

Every durable definition and semantic construct has stable identity. A Transition reference includes:

  • the definition identity shared by its revisions
  • the exact semantic revision
  • the normalized content fingerprint

Activation admits only compatible schema versions, definition kinds, and exact references. A mismatch is a definition or activation failure, distinct from a business rejection such as NotDraft.

Source maps connect canonical paths and diagnostics back to C# members and lines. That attribution makes errors useful to an author without making filesystem layout part of semantic identity.

Integration Boundaries

Relations or source adapters

Responsibility
Acquire the current observations required to evaluate the Transition.

Transition interpreter

Responsibility
Evaluate admission, branches, patches, invariants, effects, and outcome without committing external work.

Storage

Responsibility
Validate freshness, apply accepted patches, and durably record outgoing interactions under proven capabilities.

Processes

Responsibility
Coordinate Transition invocation, effect delivery, request obligations, waits, retries, and longer-running progress.

API and Presentation

Responsibility
Project typed inputs, outcomes, diagnostics, and controls without becoming execution authority.

Continue

Return to the Cohesive.Entities overview →

Build the complete AssignCarrier example →

See how Processes coordinate Transitions and requests →