Skip to content

2.20.0 – Oct 17, 2026

Choose a tag to compare

@github-actions github-actions released this 17 Oct 04:40
· 60 commits to main since this release
8570b65

2.20.0 (2026-10-17)

Consumer filtering and fifteen-minute idle reads are enabled automatically with supporting runtimes. Upgrade requirement: persistent legacy aggregate roots and implicit aggregate value parameters must declare or inherit @Aggregate, including calls to loadAggregate. See the 2.x migration guide.

For route filtering, upgrade every Runtime storage reader before enabling native-v2 writes. Filtering can be disabled independently while retaining v2 readers and old-client compatibility; see the tracking and rollout guide.

Features

  • tracking: enable consumer blueprint filtering (#501) (8570b65)

    Enable conservative consumer filtering and longer idle reads on supporting peers, with compatible route envelopes and synchronous fixture admission. Require aggregate markers for persistent legacy roots as documented in the 2.x migration guide.

  • tracking: project consumer routes into message envelopes (1f35d7a)

    Separate logical route selection from payload serialization and opaque message metadata. Negotiate native routed envelopes per transport session and retain existing object formats for older peers.

  • testing: apply consumer filters in synchronous fixtures (b3503e9)

    Reuse effective consumer preparation and header-only serialization descriptions so ordinary fixture expectations expose overly restrictive delivery filters. Preserve synchronous execution, validation order, local handler semantics and conservative admission for unknown contracts.

  • modeling: require markers for persistent aggregate roots (6f572e8)

    Reject unmarked roots when loading, creating or persisting aggregates so forgotten annotations fail visibly. Preserve independent Models, members and side-effect-free entity wrappers.

    BREAKING CHANGE: all persistent aggregate roots must declare or inherit @​Aggregate. Empty untyped roots remain available until their type is known, but cannot persist or publish aggregate events without a marked root type.

  • handling: require aggregate markers for implicit value injection (2b5de16)

    Derive payload selection from the same explicit argument roles used by the SDK, and remove the aggregate metadata exception from the consumer filter contract.

    BREAKING CHANGE: implicit legacy aggregate value parameters must declare or inherit @​Aggregate. Explicit Entity parameters, entity-context injection and custom resolver overrides retain their resolution paths.

  • tracking: filter consumer delivery on supporting peers (6a2aa0e)

    Project effective handler inputs, legacy migration inputs and compiled web routes into conservative subscription filters. Reuse snapshots across reads and acknowledge selection updates across active connections.

    Enable filtering and fifteen-minute idle waits automatically when the peer advertises support. Preserve legacy delivery, explicit cursors and tracking lifecycle behavior, with application-local overrides.

Bug Fixes

  • web: accept untyped empty JSON responses (bee2877)

    Allow bodyless HTTP replies to retain JSON representation headers while preserving custom deserialization and concrete type errors. Reuse decoded bytes and keep streaming failures on their existing path.

  • tracking: retain shared automatic web routes in consumer filters (3be6b23)

    Keep declared helper routes eligible when local registration and grouped consumer preparation choose different owners. Preserve single invocation ownership and explicit HTTP helper precedence.

  • tracking: preserve required inputs in consumer projections (fec8757)

    Project serialized batch transformations before narrowing delivery, keep every refresh listener reachable after failures, and retain proven alias and Graph boundaries. Describe socket lifecycle inputs without broadening unrelated HTTP traffic, including handshakes shared by local and tracked factories.

  • serialization: register caster batches atomically (53a745b)

    Publish a complete caster snapshot only after all candidates pass conflict checks, preventing active inputs outside an acknowledged consumer blueprint. Keep cancellation scoped to the owning registration so it cannot remove a later replacement.

  • tracking: apply cached type filters to payload names (8ac5b32)

    Use the configured regular expression as the pattern, matching server-side selection. Keep unknown payload types and unfiltered manual reads eligible.

  • web: align filtered root and socket static routes (394b37b)

    Treat omitted web paths as the root in both dispatch and server selection. Preserve static resources on class-registered socket endpoints independently of session lifecycle.

  • tracking: preserve eligible aliases and extended handler inputs (9974c4d)

    Keep partial type aliases and custom wrapper matches eligible for server delivery. Export mandatory self-payload boundaries and preserve resolver-specific selection while retaining broad delivery for incomplete type hierarchies.

  • tracking: describe automatic Model command inputs (26d6add)

    Expose the mandatory payload boundary of automatic Model tracking so these consumers participate in server filtering. Keep open targets, arrays and the unrestricted local matcher broad, and retain wrapper-based scheduled command relay.

Documentation

  • tracking: describe online filtering rollback (2fbbbd0)
  • tracking: explain staged route storage activation (09eb653)
  • handling: document aggregate markers in the 2.x upgrade guide (ca6a914)

Tests

  • tracking: await scan progress before retargeting aliases (48291ae)

    Append completion only acknowledges storage. Establish the excluded scan position before changing the alias so asynchronous admission cannot reinterpret the earlier message.

  • tracking: cover API reference routes under consumer filtering (c6a08a3)
  • tracking: preserve implicit legacy entity arguments (230d49e)

    Guard aggregate-state arguments supplied independently of the event payload. This earlier regression coverage was subsequently updated for the final 2.x contract: persistent legacy aggregate roots and implicit aggregate value parameters must declare or inherit the Aggregate annotation.

  • tracking: publish peer reads after cache admission (c0304c4)

    Make observing the initial read establish cache and pending-state readiness before deliberately clearing the cache. This prevents the initial admission from racing the reconnect scenario.

  • web: keep route fixture assets in the server module (88c21f5)

    Own static test resources alongside the transport contract so registration works with packaged SDK test artifacts as well as reactor directories.

  • tracking: synchronize consumer progress and metric observations (fdd9144)

    Retain read observations that precede expected-index publication and deduplicate progress per consumer. Await metric enqueue before snapshot fences so fast reads cannot escape the measured counts.

Chores

  • sdk: integrate current main before consumer filtering release (2e9eddd)