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.
Cohesive.Transitions Internals
How authored Transitions become durable definitions, request only the state they need, and hand accepted decisions to storage and delivery infrastructure.
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.
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.
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.
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.
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
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.
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.
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.
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.
Every durable definition and semantic construct has stable identity. A Transition reference includes:
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.
Return to the Cohesive.Entities overview →