RIDDL 2.1.1 Released
RIDDL 2.1.1 is now available.
RIDDL 2.1.1 is now available. This release of the RIDDL compiler and language tooling includes the following changes:
What’s New
What’s New
This release tightens how riddlc validate reasons about message delivery and
stream topology. Four rules changed or arrived, each ruled by the language
author and each recorded in the RIDDL Computational Model (§7, §8.1, §17). The
riddl-models corpus (190 models) validates clean against all of them.
Improvements
-
A
tellneeds a channel from its sender, and this is now an Error (msg-tell-target-unreachable). Atellis sugar for a send on the outlet connected to the target’s inlet (Computational Model §25.7), so the channel it implies must be modelled. Reachability is now computed from the sender’s OWN outlet — a processor publishes only through its own outlet, never through its context’s — where an earlier version had counted the enclosing context’s outlets as origins and silently accepted a sender with no outlet at all. -
An adaptor may address only a context (
adaptor-targets-context-only, Error). An adaptor translates between contexts; atell,sendorforwardfrom an adaptor to an entity or repository inside its own context makes it a participant in that context’s business rather than its translator. Its own portlets are exempt, since that is how an adaptor emits at all. -
A stream chain ends where its message is consumed, not at a
sinkshape.stream-source-reaches-no-sinkused to ask whether a source reaches a processor with zero outlets. Because a sender must own the outlet it sends on, any terminal processor that also records what it received — an event log writing aPersistcommand to its repository — is a flow by arity, and every source above it was reported as reaching nothing. A chain tail is now a processor with an inlet that handles every message type its inlets admit (alternation members expanded,on othercounting) and whose handling clauses never send, tell or forward a message of that same type onward. Writing a different type is a write, not a continuation. This mirrors the earlier chain-head ruling, which stopped requiring asourceshape. -
A stream graph may not contain a cycle (
stream-graph-cycle, Error). Connectors carrying one message type that form a loop would let a message circulate forever. The check is per message type, so a request/response pair between two contexts — a command one way, an event back — is two chains, not a loop. A self-loop is a cycle of one. -
Connectors between related domains are permitted.
stream-crosses-domainsnow rejects only a connector between domains that share no ancestor; sibling domains under a common parent may be wired directly.
Bug Fixes
ESMSafetyTesthad not scanned a bundle since the sbt 2 upgrade. The guard that keeps ESM-shim trigger patterns out of the published npm bundle looked for the bundle at the sbt 1 path, found nothing, and reported itself canceled on every run, locally and in CI. It now reads the sbt 2 output tree, and CI runs it on the JS row against the exact bundle that ships.
Internal
RuleIdgainsAdaptorTargetsContextOnlyandGraphCycle; the append-only rule-id ledger records them.msg-tell-target-unreachableexisted in 2.1.0 and changes severity only.ValidationPass.isStreamTailis the single tail predicate, exposed to the streaming graph walk through one hook rather than a second copy.- Test fixtures that wired a processor’s outlet to its own inlet are now real chains.
- Engineering notes for each ruling are in
NOTEBOOK.mdandCLAUDE.md.