Entity repository
- What it stores or supplies
- Identity-addressed entity observations, projected reads, writes, concurrency tokens, and optional atomic outbox evidence.
- Who owns the meaning
- Cohesive.Entities and its Transitions.
Building Blocks
Connect entities, queries, Processes, and derived views to physical storage with explicit durability, concurrency, atomicity, and capability evidence.
Cohesive.Storage is where semantic decisions become durable. It persists entity observations, supplies physical data to Relations, commits Process progress, and maintains derived views without moving business meaning into a database-specific repository layer.
The semantic blocks say what must be preserved. Storage integrations say how a particular database, index, or durable store preserves it. When a backend cannot provide the required atomicity, concurrency, completeness, ordering, or delivery behavior, the integration returns capability diagnostics instead of silently weakening the operation.
The repository surface is deliberately small. A caller can request only the fields needed for a decision, then commit the accepted candidate state against the concurrency token it observed:
var current = await loads.TryGet(
context: context,
id: loadId,
options: EntityReadOptions
.ForFields(nameof(Load.Status), nameof(Load.CarrierId))
.WithPartitionKey(tenantId));
if (current is null)
return AssignLoadResult.NotFound;
var committed = await loads.Upsert(
context: context,
write: new EntityWriteRequest(
Entity: candidateState,
ExpectedConcurrencyToken: current.ConcurrencyToken));Here, loads is an IEntityRepository and candidateState is the observation produced after an accepted entity Transition. The same repository contract can also expose typed object mapping, batch-write capabilities, atomic outbox commits, and replayable Process Transition receipts.
The guided walkthrough creates an in-memory repository for one entity, writes and reads semantic state, adds optimistic concurrency, and registers the same repository as a bounded Relations source.
Open the Getting Started guide →
Storage provides several related physical boundaries rather than one universal repository:
An observation is the common state carrier. It keeps semantic shape, identity, version, field values, and lineage independent of a provider's document, row, or SDK type.
A conventional repository often grows around the conveniences of its first database. Queries, partition assumptions, concurrency behavior, outbox logic, and workflow checkpoints then become provider-specific application code. Cohesive makes these boundaries explicit so the system can validate what a storage binding preserves.
Storage does not run entity rules, reinterpret queries, or decide Process control flow. It surrounds those interpreters with physical evidence and durable commits.
For an entity operation, the execution environment reads the required state, evaluates the Transition, and asks a repository to commit the accepted candidate against fresh concurrency evidence. If the decision emitted an effect, an outbox-capable repository can make the state change and its canonical envelopes durable together.
For a Process activation, the runtime advances the compiled continuation and asks IProcessDurableStore to commit the resulting checkpoint as one successor. For a Relation evaluation, source readers acquire bounded facts while the Relations evaluator retains query authority. Materialization runtimes connect source progress, derived output, target generations, and promotion through their own explicit storage ports.
IEntityRepository is scoped to one logical entity definition. Its core operations are identity-based reads and writes over immutable snapshots. Reads can include a partition hint, expected version, expected concurrency token, and field selection. Writes can carry an opaque optimistic-concurrency token returned by the provider.
Batch requests state their required atomicity: independent writes, same-partition atomicity, or all-or-nothing behavior. The repository advertises which forms it supports and its item limit. The default contract falls back only when no atomic batch guarantee was requested.
IEntityOutboxRepository adds an atomic entity-state and canonical-envelope commit. This is the physical boundary for the transactional outbox pattern when a direct Transition emits events or requests.
When a Process invokes a Transition, IEntityTransitionOperationRepository can instead commit the candidate entity state and the exact Process operation receipt together. Replay returns that receipt without applying the entity decision again. The resulting interaction envelopes are then admitted to the Process outbox, which remains publication authority for that Process occurrence.
Storage contributes physical acquisition to Relations. It does not own another query abstraction.
An EntityRelationQuerySourceRegistration binds one graph-qualified shape to a source reader, physical source identity, selectors, capability profile, and hard limits. The reader may supply bounded enumeration, point or batch identity reads, relationship-key batches, selected fields, and completeness evidence. Canonical Relations interpretation still owns filters, joins, projection, aggregation, ordering, and paging.
This distinction lets PostgreSQL, Cosmos DB, or an in-memory repository acquire the same semantic facts through different physical strategies without turning provider syntax into application query meaning.
Cohesive.Storage.Processes defines the physical durability boundary for a Process. One ProcessDurableCheckpoint combines the current continuation with attempt and activation receipts, accepted inbox inputs, outgoing interaction envelopes, completed host operations, durable request state, worker ownership, and lifecycle control.
IProcessDurableStore uses compare-and-swap revisions, worker fences, and deterministic commit identities. A legal update replaces the checkpoint as one aggregate mutation. An exact retry can replay the retained result; reused identity with different content is rejected.
The current package includes ProcessDurableRuntime and the copy-on-write InMemoryProcessDurableStore reference implementation. The in-memory store is a semantic test oracle, not a production durability provider. Production implementations must preserve the same aggregate and fencing contract.
Materialization turns a selected Relation output into maintained physical data such as a search index or denormalized serving view. The Relation remains authority for dependency, lineage, and output meaning; Storage owns rebuild, incremental synchronization, target lifecycle, and progress evidence.
A materialization definition declares consistency, freshness, failure, source, target, and bounded-work requirements. Planning derives affected roots from the Relation dependency manifest. Execution hydrates through the exact Relations plan, writes to an isolated target generation, catches up changes, validates readiness, and promotes through a fenced routing boundary.
The materialization records the exact Relation compilation request, selected output, and synchronization requirements.
Cohesive.Entities defines state, invariants, Transitions, decisions, and outgoing effects.Cohesive.Relations defines queries, dependency, lineage, and derived outputs; Storage supplies bounded physical facts.Cohesive.Processes defines durable coordination; Storage persists its checkpoints and operation evidence.Cohesive.Api binds entity and Process operations to transport-neutral endpoints without taking storage authority.Cohesive.Presentation projects entity, Process, and materialization status from the same attributable evidence.The Internals page covers repository capabilities, atomic Transition receipts, Process compare-and-swap and worker fencing, canonical source registration, materialization impact planning, rebuild and convergence, routing generations, progress and settlement, bounded control, and removed compatibility surfaces.