Cohesive Systems logoCOHESIVE SYSTEMS

Transitive Closure Rather Than Lowest Common Denominator

A common critique of any cross-provider abstraction is that it must flatten every target into the lowest common denominator.

The critique is valid when the abstraction is only a thin uniform wrapper. If PostgreSQL, Cosmos DB, Kafka, Elastic, Temporal, Orleans, and cloud infrastructure are all hidden behind a single generic facade, the facade can only expose what all targets already share. Everything distinctive becomes unreachable or has to leak through undocumented side channels.

Cohesive is designed against that failure mode. It does not treat provider differences as details to erase. It treats them as capabilities to model, compose, diagnose, and project from a semantic source of truth.

The goal is not the intersection of all backends. The goal is the transitive closure of what a system model can require, what each target can provide, what can be compiled directly, what can be composed from other facilities, and where a developer must intentionally cross into target-specific code.

The Lowest Common Denominator Trap

Lowest-common-denominator abstractions usually start with a reasonable goal: make application code portable across targets.

The problem is the definition of portability. If portability means "only use the features every target has in exactly the same way," the abstraction becomes smaller than every real target beneath it.

For databases, that usually means hiding indexes, partition keys, constraints, change feeds, transactional guarantees, query planners, native operators, consistency levels, and execution diagnostics behind a generic repository API.

For workflow and runtime targets, it means hiding durable timers, replay rules, activity retry policies, actor placement, message ordering, leases, queues, streams, supervision, and compensation behavior behind generic "background job" or "process" vocabulary.

For infrastructure, it means hiding regions, identity boundaries, deployment topology, network policy, scaling behavior, secrets, managed resources, and provider-specific service limits behind a flat deployment model.

That kind of abstraction reduces the developer's precision. It makes easy cases look tidy, but it gives the system no language for explaining why a target is a good fit, a partial fit, or a bad fit.

Cohesive takes the opposite stance: provider differences matter because they are part of the system's operational semantics.

Escape Hatches Are Part of the Model

Cohesive's bottom-up posture matters here. A Cohesive model is not meant to lock the developer away from PostgreSQL, Cosmos DB, Kafka, Elastic, Temporal, Durable Task, Orleans, a cloud SDK, or a generated codebase.

When a query is compiled to PostgreSQL, the developer should be able to reach the relational target deliberately:

  • Add a backend-specific index strategy.
  • Override part of a generated query.
  • Attach a PostgreSQL operator or extension.
  • Inspect the generated SQL and query plan.
  • Bind a relation projection to a materialized view.
  • Replace a generated path with hand-authored target code where precision requires it.

When a query is compiled to Cosmos DB, the equivalent escape hatch is different:

  • Make the partition key explicit.
  • Tune continuation and pagination behavior.
  • Use Cosmos-specific indexing policy.
  • Shape a query around document locality.
  • Integrate with change feed processing.
  • Declare when cross-partition behavior is intentional.

The important point is not that every escape hatch should be convenient. The important point is that escape hatches should be visible, typed where possible, reviewable, and connected back to the semantic model they extend.

An escape hatch is not a failure of abstraction. It is how a precise abstraction acknowledges that the target remains real.

Capabilities, Not Facades

Cohesive models backend targets through capabilities rather than through a single facade.

A capability is a statement about what a target can do and under which conditions:

PostgreSQL
  supports:
    relational joins
    transactional uniqueness
    foreign-key constraints
    materialized views
    JSON operators
    advisory locks
    LISTEN/NOTIFY
 
Cosmos DB
  supports:
    partitioned document storage
    request-unit governance
    change feed processing
    tunable consistency
    server-side indexing policy
    transactional batch within a partition

A Cohesive requirement can then be matched against target capabilities:

Query:
  requires:
    relation traversal
    filtered ordering
    stable pagination
    tenant isolation
 
Transition:
  requires:
    single-entity atomicity
    uniqueness by tenant
    reliable effect publication

This makes the abstraction larger, not smaller. It can express the semantic need, the target's native support, possible compiled strategies, and the cases where the selected backend cannot satisfy the requirement without additional runtime support.

That is the sense in which Cohesive aims for transitive closure. It is not "PostgreSQL and Cosmos both have feature X, therefore Cohesive exposes X." It is "the model requires behavior R; target A provides it natively, target B can realize it through strategy S plus constraint C, target C cannot realize it without an explicit extension."

Diagnostics Over Silent Degradation

The worst abstraction does not merely hide a capability. It silently degrades semantics.

A query that needs stable ordering should not quietly become an unordered scan. A transition that needs atomic uniqueness should not become a best-effort check. A workflow that needs durable recovery should not become an in-memory callback. A tenant isolation requirement should not become a naming convention.

Cohesive makes these mismatches diagnostic:

Cross-entity atomic transition

Possible Diagnostic
Selected target supports atomic writes only within one partition.
Useful Outcome
Choose a different target, revise the partition model, or compile to a process with compensation.

Relational query with filtered joins

Possible Diagnostic
Document target cannot realize this shape without a projection or denormalized read model.
Useful Outcome
Generate a projection, change the query shape, or route this query to a relational target.

Reliable external effect

Possible Diagnostic
Transition writes state and emits an integration message without a shared durability boundary.
Useful Outcome
Compile an outbox, use a change feed, or bind the effect to a durable workflow.

History-sensitive entity behavior

Possible Diagnostic
Current-state persistence loses information required by the invariant.
Useful Outcome
Emit durable events, use event sourcing, or persist the required historical observation explicitly.

Low-latency search over mutable data

Possible Diagnostic
Authoritative store can answer the query but does not satisfy latency or indexing requirements.
Useful Outcome
Project to a search target and make read-model freshness part of the contract.

This is the Dijkstra-shaped part of the design: abstractions should enable precision. A useful abstraction is not vague convenience. It gives the system a vocabulary for saying exactly what is required, exactly what is available, and exactly where a proof obligation has not been discharged.

Compiler and HAL Tactics

Cohesive is closer to a compiler or an operating-system hardware abstraction layer than to a conventional library facade.

A compiler does not pretend every CPU architecture is identical. It has an intermediate representation, a target description, optimization passes, calling conventions, intrinsic functions, feature flags, and diagnostics. When a target has a native instruction, the compiler may use it. When it does not, the compiler may lower the operation into a sequence of simpler operations. When the target cannot support the required semantics, compilation fails or asks for a runtime helper.

An OS HAL follows a similar pattern. Hardware differences are not erased. They are organized behind contracts, capability discovery, driver hooks, interrupt models, memory models, and fallback paths. The kernel can target many devices because it has a disciplined way to separate portable semantics from target-specific control.

Cohesive can use the same tactics:

Intermediate representation

Compiler / HAL Analogy
IR separates source language from machine code.
Cohesive Interpretation
The semantic system graph separates domain requirements from concrete storage, runtime, API, and infrastructure targets.

Target descriptions

Compiler / HAL Analogy
Backends declare registers, instructions, memory rules, and calling conventions.
Cohesive Interpretation
Providers declare transaction scope, query operators, partition behavior, consistency, indexing, workflow durability, and deployment limits.

Lowering

Compiler / HAL Analogy
High-level operations become target-specific instruction sequences.
Cohesive Interpretation
A relation, transition, or effect becomes SQL, document queries, projections, outbox entries, workflow steps, actor messages, or generated API code.

Intrinsics

Compiler / HAL Analogy
Source code can request a target-native operation intentionally.
Cohesive Interpretation
A model or generated artifact can bind to PostgreSQL extensions, Cosmos change feed, provider SDKs, or target-specific runtime hooks.

Optimization

Compiler / HAL Analogy
The same program can be optimized differently per architecture.
Cohesive Interpretation
The same query or projection can choose indexes, denormalization, batching, caching, or materialization strategies per backend.

Diagnostics

Compiler / HAL Analogy
Unsupported instructions, unsafe casts, and ABI mismatches are compile-time errors.
Cohesive Interpretation
Capability mismatches become model diagnostics rather than runtime surprises.

The abstraction is therefore not a ceiling. It is a coordination layer between semantic intent and target-specific realization.

SQL as a Precedent

SQL is a useful precedent because it is both portable and target-specific.

The relational model gives developers a shared language for selecting, joining, filtering, grouping, constraining, and updating data. That shared language did not prevent PostgreSQL, SQL Server, Oracle, MySQL, SQLite, and other engines from building distinct planners, indexes, isolation behavior, extensions, execution strategies, and operational profiles.

The strongest SQL systems are not successful because they expose only the features common to every engine. They are successful because the common relational core is valuable, the optimizer has target-specific freedom, and providers expose extensions when the standard vocabulary is not enough.

Cohesive adopts the same lesson:

  • Define precise shared semantics where the domain has real structure.
  • Let targets optimize and specialize beneath those semantics.
  • Surface target-specific capabilities deliberately.
  • Diagnose when a model assumes a capability the selected target does not have.
  • Keep generated artifacts inspectable and overridable.

That is a higher bar than a generic repository or universal adapter. It also preserves more power.

Practical Design Implications

The practical proposal is to make capability modeling part of the product surface, not an internal implementation detail.

First, Cohesive exposes a capability graph for each selected target. A developer can ask: what does this target support natively, what does Cohesive synthesize, what requires an auxiliary runtime, and what remains unavailable?

Second, generated artifacts carry their provenance. A SQL query, document projection, API route, workflow, actor, index, or infrastructure resource points back to the semantic requirement that produced it.

Third, overrides are explicit and local. If a developer replaces a generated query with target-specific SQL, the model knows that this projection has a native override rather than treating the change as a forked artifact outside governance.

Fourth, target selection is explainable. Cohesive can say why PostgreSQL is a better realization for one relation, why Cosmos is a better realization for one entity family, why Elastic is a projection rather than an authoritative store, or why a transition needs a durable workflow instead of a simple request handler.

Fifth, failure is precise. The right answer is sometimes "this model cannot be realized on this target with these guarantees." That is not a limitation of Cohesive. It is the abstraction doing useful work.

The lowest-common-denominator critique assumes that abstraction means hiding the target.

Cohesive means something stricter: it makes the semantic model precise, makes target capability explicit, compiles what can be compiled, extends where the target has more to offer, and produces diagnostics where the requested behavior does not follow from the selected substrate.

That is not lowest common denominator. It is disciplined transitive closure.