Skip to main content
Topic and subscription runtime facts determine how messages are grouped, ordered, delivered, and dispatched into execution pools. These declarations sit under Model.runtime.topics and Model.runtime.subscriptions. Two scopes exist: transport semantics can be declared once per topic, or independently per subscription, but never both at once for the same topic.
L0 topics declare only which schemas a channel may carry and how one logical message is identified. All grouping and ordering facts are L1 runtime properties. The same logical channel may be realized differently by different subscribers.

Exclusive scope rule

For any topic, grouping and ordering are declared at exactly one of two scopes:
  • Topic-scoped: TopicRuntime declares one domain for the whole topic. Every subscriber observes those semantics.
  • Subscription-scoped: each SubscriptionRuntime declares its own semantics independently.
These are different declaration modes, not a default and an override. Validation rejects a model that uses both for one topic.
There is no inheritance, no override, and no fallback chain. Omitting ordering leaves the scope open; writing ordering: none is an explicit negative that claims the scope.

Topic-scoped example

Topic-scoped transport semantics

Subscription-scoped example

Subscription-scoped transport semantics

TopicRuntime

  • grouping: maps each schema into a common grouping domain. Tuple positions correspond across schemas, so all mapped tuples share one arity. Every carried schema must be mapped.
  • ordering:
    • global: one precedence relation across all messages in scope
    • within_group: precedence among messages of the same declared grouping domain (requires grouping)
    • none: explicit “this transport orders nothing”
    • omitted: no precedence is declared at this scope (scope remains open)

SubscriptionRuntime

Delivery semantics

SubscriptionDispatch

Dispatch connects transport semantics to execution topology. The referenced pool names the execution population that receives deliveries.
  • routing is optional. Absence means deliveries execute within the pool, with no member-affinity fact.
  • key: grouping_key routes by the effective grouping domain, whichever scope declared it. This requires a keyed grouping to be in effect.
Dispatch preserves existing precedence and never invents it. Where a precedence exists, a conforming runtime must not admit a later message in a manner that lets it overtake an earlier, incomplete message within the same effective group.
Dispatch preserving order is an obligation of the realization, not a substitute for declaring transport precedence. A dispatch declaration alone proves no ordering.

Grouping vs ordering

Grouping and ordering are deliberately separate declarations because a transport may provide one without the other:
  • An unordered queue with consistent-hash workers provides grouping without ordering.
  • A global sequential stream provides ordering without grouping.
Serialization proofs need only grouping: same key implies same routing domain, which implies same owning member on a serial pool. Ordering proofs need grouping plus a declared precedence source. See the Operations requirements page for how these requirements are discharged.
For the full semantics of MemberAssignment and ExecutionPool, see Routers and Pools.