Skip to content

Bump the nuget-minor-patch group with 10 updates - #174

Open
dependabot[bot] wants to merge 2 commits into
mainfrom
dependabot/nuget/nuget-minor-patch-79a02166ff
Open

Bump the nuget-minor-patch group with 10 updates#174
dependabot[bot] wants to merge 2 commits into
mainfrom
dependabot/nuget/nuget-minor-patch-79a02166ff

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Aug 8, 2026

Copy link
Copy Markdown
Contributor

Updated AndreGoepel.Core from 1.0.0 to 1.0.1.

Release notes

Sourced from AndreGoepel.Core's releases.

1.0.1

What's Changed

New Contributors

Full Changelog: andregoepel/core@v1.0.0...v1.0.1

Commits viewable in compare view.

Updated AndreGoepel.Marten.Identity.Blazor from 1.8.0 to 1.9.1.

Release notes

Sourced from AndreGoepel.Marten.Identity.Blazor's releases.

1.9.1

What's Changed

Full Changelog: andregoepel/marten-identity@v1.9.0...v1.9.1

1.9.0

What's Changed

Full Changelog: andregoepel/marten-identity@v1.8.1...v1.9.0

1.8.1

What's Changed

Full Changelog: andregoepel/marten-identity@v1.8.0...v1.8.1

Commits viewable in compare view.

Updated bunit from 2.8.6 to 2.9.0.

Release notes

Sourced from bunit's releases.

2.9.0

Changed

  • Update to stable package of AngleSharp.Css

Commits viewable in compare view.

Updated Marten from 9.19.0 to 9.22.5.

Release notes

Sourced from Marten's releases.

9.22.5

Two source-generator and test-harness fixes that both surfaced on projections built through AddProjectionWithServices, plus the JasperFx 2.42.2 adoption they ride on.

Fixes

The source generator no longer breaks a projection that takes dependencies (#​5192)

The bundled JasperFx.Events.SourceGenerator registers an EventProjection's discovered published document types (#​4166) by writing into your partial class. It used to emit a parameterless constructor to do it, which failed two ways for exactly the projections that need dependencies injected.

It broke the build outright against a primary constructor. C# requires every other constructor to chain through the primary one, so this failed with CS8862 inside the generated <T>.TypeRegistration.g.cs:

public partial class MyProjection(ILogger<MyProjection> logger) : EventProjection
{
    public override ValueTask ApplyAsync(IDocumentOperations operations, IEvent e, CancellationToken cancellation)
    {
        operations.Store(new Thing());
        return new ValueTask();
    }
}

And where it did compile, it silently did nothing. A projection registered through AddProjectionWithServices is built by the container, which calls the dependency-taking constructor — so the generated parameterless one never ran and the published types went unregistered. That also left the projection's teardown targets unregistered, so a rebuild did not wipe its documents.

Registration now rides an override of ProjectionBase.PublishedTypes(), which does not care how the instance was constructed.

Affects 9.22.3 and 9.22.4. Earlier versions discovered published types syntactically, so only an explicit ops.Store<Doc>(x) produced a registration and the far more common ops.Store(x) produced none — which meant the constructor was rarely emitted at all.

One behavior change to be aware of: the generator used to skip registration entirely when your class already had an explicit parameterless constructor, a guard that existed only because you cannot add a second one. An override has no such conflict, so those projections now get their published types registered too. That is the intended #​4166 behavior, but on upgrade it can newly provision document storage — and newly register teardown targets — for a projection that was quietly getting neither. If a projection writes into storage that must not be truncated on rebuild, set DeletePublishedTypesOnTeardown = false.

EventProjectionScenario no longer spends its wall clock asleep (#​5195, in part)

Almost none of a scenario's time was work. The harness wipes the event store and then starts the daemon, so the high-water agent's first look saw an empty store, read CaughtUp, and settled into SlowPollingTime — one second by default. Every append then raced a sleeping agent, and because the agent returns to CaughtUp after each batch drains, the cost recurred at every batch boundary. Since a boundary is how a scenario says "these appends must land in different daemon batches", the more precisely a test described its batching, the slower it got.

A scenario owns both the appends and the daemon that must notice them, so it now says so directly, through an in-process IDaemonWakeup — a semaphore release, no database round trip and no LISTEN/NOTIFY. Nothing about your store's polling configuration changes.

batch boundaries before after
1 ~1290ms ~300ms
3 ~3357ms ~815ms

A flat ~250ms per boundary remains, from a hard-coded poll delay in WaitForNonStaleDataAsync. That is the other half of #​5195 and is still open.

Dependencies

JasperFx / JasperFx.Events 2.42.2. Adopting it also enrolls Marten in the strong-typed identity event-sourcing compliance suite that landed in 2.42.0 (IComplianceStoreRegistrar.RegisterValueType<T>()), taking the shared cross-store suite to 167 passing tests against Marten.

9.22.4

What's Changed

Full Changelog: JasperFx/marten@V9.22.3...V9.22.4

9.22.3

What's Changed

Full Changelog: JasperFx/marten@V9.22.1...V9.22.3

9.22.1

Security release. Upgrade is recommended for anyone using sharded tenancy together with Events.UseTenantPartitionedEvents.

A tenant id was interpolated into a double-quoted PostgreSQL identifier without doubling an embedded double quote, so a tenant id containing one could terminate the identifier and execute additional SQL statements. This is a different class from the two advisories previously published on this repository, both of which were the single-quoted string-literal class; neither of those fixes addressed this.

You are affected only if you use sharded tenancy, have UseTenantPartitionedEvents enabled, and your application passes attacker-influenced input as a tenant id. Note that the reachable surface includes ordinary session resolution, not just administrative provisioning calls — GetTenantAsync / FindOrCreateDatabase auto-provision an unknown tenant. Applications using tenant ids from a trusted fixed set are not exploitable.

Affected versions: 9.4.0 through 9.22.0.

Full details, including remediation guidance for existing data, are in the security advisory: GHSA-3vp4-34pf-2rcw

What changed

  • PerTenantEventSequences.QuotedSequenceName escapes embedded quotes, matching quote_ident/%I so the name still resolves to the same object the quick-append function finds. Covers the create, drop, schema-apply and cleanup paths.
  • BulkEventAppender no longer builds an unquoted sequence name from a suffix read back out of the tenants table. This also fixes a functional bug: PreserveSourceSequence bulk imports previously failed with 42601 for hyphenated and GUID tenant ids under sharded tenancy.
  • ShardedTenancy validates tenant ids destined for DDL, closing a long-standing asymmetry with the DefaultTenancy provisioning path. It is a narrow denylist rather than the existing identifier allowlist, so hyphenated and GUID tenant ids keep working.

Dependency

Requires Weasel.Postgresql 9.21.1, which escapes partition bound values (JasperFx/weasel#​416). Both halves are needed; the dependency is pulled in automatically.

Credit to Barak Srour (Apiiro) for the report.

9.22.0

The partitioning feature is new, but otherwise this was all about CritterWatch improvements for a huge installation

What's Changed

Full Changelog: JasperFx/marten@V9.21.0...V9.22.0

9.21.0

Highlights

A small, low-risk release: two bug fixes reported against 9.20.x, a LINQ ordering fix, a Newtonsoft serialization fix, and a new health-check overload for Wolverine-managed daemon distribution.

[!NOTE]
There is a change to the mt_quick_append_events PostgreSQL function in this release, and applying it is NOT mandatory or required.

You do not need to patch your database, schedule a migration, or coordinate a deployment window to take 9.21.0. The client-side half of the #​5062 fix ships in the assembly, so upgrading the NuGet package alone is sufficient — 9.21.0 is correct against the function version you already have deployed.

Under the default AutoCreate.CreateOrUpdate the function is simply refreshed the next time Marten ensures event storage exists (a CREATE OR REPLACE FUNCTION, no lock on your event data). If you run AutoCreate.None with db-patch / db-apply, your next patch will contain one extra CREATE OR REPLACE FUNCTION … mt_quick_append_events statement — apply it whenever it suits your normal cadence. See the migration guide for details.

Bug Fixes

mt_quick_append_events returned {NULL} for an empty event array (#​5062, #​5088)

array_length('{}', 1) is NULL in PostgreSQL rather than 0, so calling the bulk append function with no events returned a bigint[] whose single element was NULL. Npgsql could not read that into long[], and the resulting InvalidCastException was thrown from the batch's post-processing loop — where it displaced whatever exception had actually made the append fail. Callers were left with an unrelated, non-retryable error instead of the real one; for the reporter that dead-lettered Wolverine messages which would otherwise have been retried.

Fixed on three fronts:

  • The function now COALESCEs the array length, so an empty append means what it says: zero events appended, final version unchanged.
  • The append operation no longer reads the returned array when the batch carries no events — this is what makes the fix effective without any database change.
  • The one code path in Marten that could reach the function with empty arrays (ProjectionUpdateBatch.WaitForCompletion, for an Append side effect that ended up with no events) no longer issues the call.

OrderBy against a dictionary indexer dropped the key (#​5063, #​5073)

OrderBy(x => x.SomeDictionary["key"]) generated SQL that ignored the indexer key, so the ordering was wrong (or arbitrary) rather than failing loudly.

Lazy LINQ sequences serialized as objects under Newtonsoft (#​5076, #​5080)

A document property holding a deferred-execution sequence (Select(...), Where(...) without a materializing call) was written by Newtonsoft as an iterator object rather than a JSON array, so it would not round-trip. These are now written as plain arrays.

IMessageBatch is called concurrently (#​5065, #​5085)

Not a behavior change, but a documentation fix worth flagging if you implement IMessageBatch yourself: the async daemon raises projection side effects from multiple threads at once (measured at up to 8 concurrent publishers across 10 threads for a single-stream projection catching up). The interface previously said nothing about this. An implementation that appends to an unsynchronized collection will silently drop messages — the same hazard, in a real outbox, that showed up here as a "flaky" test.

New

Provider-aware databaseFilter for the high-water health check (#​5061, #​5089)

AddMartenHighWaterHealthCheck's databaseFilter is captured at registration time, so it cannot resolve services — which makes it unable to express "the databases this node currently owns" when ownership is runtime state. That is precisely the case under Wolverine-managed daemon distribution, where agents are assigned per (database, tenant) and rebalanced over a node's lifetime.

There is now an overload whose filter receives the IServiceProvider and is re-evaluated on every probe:

Services.AddHealthChecks().AddMartenHighWaterHealthCheck(
    (services, database) => services.GetRequiredService<IWolverineRuntime>()
        .Agents.AllLocallyOwnedDatabaseIds()
        .Any(id => id.Name.EqualsIgnoreCase(database.Identifier)),
    staleThreshold: TimeSpan.FromSeconds(30),
    includeExternallyManaged: true);
 ... (truncated)

## 9.20.2

## What's Changed
* Fix NgramIndex to match NgramSearch's unaccent-aware mt_grams_vector expression by @​dat-honguyen in https://github.com/JasperFx/marten/pull/5060

## New Contributors
* @​dat-honguyen made their first contribution in https://github.com/JasperFx/marten/pull/5060

**Full Changelog**: https://github.com/JasperFx/marten/compare/V9.20.1...V9.20.2

## 9.20.1

Two real improvements:
1. Less log noise and faster/cleaner shutdowns at production time
2. Adjustments to the "high water mark" detection to ignore idle transactions from advisory locks in advancing the high water mark. This was a side effect of the extra work we did in 9.18 to try to stop event skipping from slow transactions

## What's Changed
* fix(#​4953): allocation fence keeps idle advisory-lock sessions from holding gap skips forever by @​jeremydmiller in https://github.com/JasperFx/marten/pull/5057
* Adopt JasperFx.Events 2.36.2: clear resolved daemons on coordinator stop, idempotent AddAsyncDaemon by @​jeremydmiller in https://github.com/JasperFx/marten/pull/5058


**Full Changelog**: https://github.com/JasperFx/marten/compare/V9.20.0...V9.20.1

## 9.20.0

Bug fixes around permutations of the natural key usage, new convenience mechanisms for querying for event store data

## What's Changed
* chore(deps-dev): bump find-my-way from 9.5.0 to 9.7.0 by @​dependabot[bot] in https://github.com/JasperFx/marten/pull/5045
* chore(deps-dev): bump postcss from 8.5.14 to 8.5.23 by @​dependabot[bot] in https://github.com/JasperFx/marten/pull/5046
* Retire the previous natural key row when the key changes (#​5041) by @​jeremydmiller in https://github.com/JasperFx/marten/pull/5049
* Add FetchStreamStatePlan + FetchStreamPlan: raw event stream fetches as batchable query plans by @​uniquelau in https://github.com/JasperFx/marten/pull/5043
* StreamEventState + StreamEvents result types for Marten.AspNetCore by @​jeremydmiller in https://github.com/JasperFx/marten/pull/5053
* Natural key table: scope the FK guard, and land the partitioned-FK repro (#​5044) by @​jeremydmiller in https://github.com/JasperFx/marten/pull/5050
* Adopt JasperFx.Events 2.36.0: shard failure classification, drain timeout docs, natural key extraction by @​jeremydmiller in https://github.com/JasperFx/marten/pull/5054


**Full Changelog**: https://github.com/JasperFx/marten/compare/V9.19.0...V9.20.0

Commits viewable in [compare view](https://github.com/JasperFx/marten/compare/V9.19.0...V9.22.5).
</details>

Updated [Npgsql](https://github.com/npgsql/npgsql) from 9.0.4 to 9.0.5.

<details>
<summary>Release notes</summary>

_Sourced from [Npgsql's releases](https://github.com/npgsql/npgsql/releases)._

## 9.0.5

v9.0.5 contains several minor bug fixes.

[Milestone issues](https://github.com/npgsql/npgsql/milestone/131?closed=1)

**Full Changelog**: https://github.com/npgsql/npgsql/compare/v9.0.4...v9.0.5

Commits viewable in [compare view](https://github.com/npgsql/npgsql/compare/v9.0.4...v9.0.5).
</details>

Updated [Quartz.Extensions.Hosting](https://github.com/quartznet/quartznet) from 3.18.2 to 3.19.1.

<details>
<summary>Release notes</summary>

_Sourced from [Quartz.Extensions.Hosting's releases](https://github.com/quartznet/quartznet/releases)._

## 3.19.1

Quartz.NET 3.19.1 is a small bug fix release with two targeted fixes: `DailyTimeIntervalTrigger` no longer gets stuck in an infinite fire loop on DST spring-forward days, and `StdSchedulerFactory.GetScheduler(schedName)` now creates the scheduler when the name asked for is its own. There are no API or schema changes, so it is a drop-in upgrade from 3.19.0.

## Highlights

- **`DailyTimeIntervalTrigger` no longer spins on DST transition days** — `GetFireTimeAfter` could return a time at or before the one it was given, which makes `QuartzSchedulerThread` fire the trigger, compute the same next fire time, and fire again — pinning a CPU core and flooding the log. Two independent causes, both on a spring-forward day: the DST correction added for #​1114 was applied to every interval size and in either direction (so every interval of an hour or less was affected, in every DST time zone), and the daily rollover to `StartTimeOfDay` reused whatever UTC offset the previous fire time carried (so in time zones that move the clock at midnight, such as Chile, `StartTimeOfDay` 00:00 resolved to an instant *before* the transition — the same instant that was passed in). Verified across 3024 combinations of 12 time zones, both transitions, 21 intervals and 6 start times: 468 combinations produced non-advancing fire times before, none do now. (#​3190, fixes #​332)
  - **Behavior change worth noting:** the same fix stops sub-hour triggers silently dropping the last hour of a **fall-back** day. A 5-minute trigger now fires 300 times through the 25-hour day, ending at 23:55 local, instead of 288 times ending at 22:55.
- **`StdSchedulerFactory.GetScheduler(schedName)` creates its own scheduler** — asking a factory for the scheduler it is configured to produce returned `null` until somebody had called `GetScheduler()` first. It now creates it. Any other name stays a pure lookup, so probing for a scheduler somebody else owns still has no side effects, and the name comparison is case-insensitive to match how `SchedulerRepository` indexes names. The DI factory has behaved this way since #​2845; this brings the property-configured factory in line. (#​3188, reported in #​2786, originally proposed in #​360)

## What's Changed
* Create the scheduler when it is looked up by its own name (#​360) by @​lahma in https://github.com/quartznet/quartznet/pull/3188
* Fix DailyTimeIntervalTrigger infinite fire loop during DST spring-forward (#​332) by @​lahma in https://github.com/quartznet/quartznet/pull/3190


**Full Changelog**: https://github.com/quartznet/quartznet/compare/v3.19.0...v3.19.1


## 3.19.0

Quartz.NET 3.19.0 is a feature release: it adds node affinity for clustered scheduling, a fluent cron-expression builder, and richer `L`/`LW` day-of-month expressions, plus clock-jump resilience and a modernized build and publishing pipeline. The public API is unchanged (all additions are additive), so it is a drop-in upgrade — with two things to note: the new node-affinity columns are an **optional** schema migration (the feature degrades gracefully without them), and a handful of previously-broken `L`/`LW`/`W` cron expressions now fire correctly (see below).

## Highlights

- **Node affinity for clustered trigger pinning** — pin a trigger to a preferred node with `TriggerBuilder.WithPreferredNode(...)`; the node is preferred for acquisition but the trigger is still stolen on failover so it is never stranded if that node goes down. Adds optional `PREFERRED_NODE` / `PREFERRED_NODE_AUTO` columns for ADO.NET job stores (`database/schema_30_add_preferred_node.sql`); when the columns are absent the scheduler logs a warning and behaves exactly as before. (#​3013, #​3144)
- **Fluent `CronExpressionBuilder`** — compose cron expressions programmatically, one field at a time, instead of hand-writing the string — handy when a schedule is assembled from user input such as a scheduling UI. (#​3139)
- **`L` and `LW` combinable with other day-of-month values** — the day-of-month field now accepts expressions such as `1,15,L` and the new `LW-n` / `L-nW` grammar. This also corrects several previously-buggy edge cases: `29W`/`31W` no longer silently skip short months, `L-30W` no longer throws mid-schedule, and `1,15W` now applies `W` to each day rather than only the first. **These corrections change the fire times of a few expressions that were previously broken** — review any stored `L`/`LW`/`W` day-of-month expressions. (#​2759)
- **Resilience to system clock jumps** — the misfire handler and cluster manager now clamp their sleep intervals after the system clock jumps forward or backward, so a clock step no longer causes a busy-spin or an absurdly long sleep. (#​3147, fixes #​1508)
- **Modernized build & publishing** — the build orchestrator moved from the unmaintained NUKE to Fallout (#​3163), and packages now publish to nuget.org via GitHub OIDC **trusted publishing** rather than a stored API key. Dependencies were also refreshed (#​3151).

**Note for `CronScheduleBuilder` users:** `AtHourAndMinuteOnGivenDaysOfWeek` / `WeeklyOnDayAndHourAndMinute` now emit textual day-of-week names (e.g. `MON,WED` rather than `2,4`). The schedules are identical, but the generated `CRON_EXPRESSION` string differs — relevant only if you compare stored cron strings byte-for-byte.

## What's Changed
* Serve Blazor plumbing under custom DashboardPath for prefix-forwarding reverse proxies (3.x) (#​3134) by @​lahma in https://github.com/quartznet/quartznet/pull/3137
* Add fluent CronExpressionBuilder for building cron expressions programmatically (3.x) by @​lahma in https://github.com/quartznet/quartznet/pull/3139
* Support for specifying 'L' and 'LW' with other days in day-of-month field by @​lahma in https://github.com/quartznet/quartznet/pull/2759
* Add preferred node (node affinity) for cluster trigger pinning by @​lahma in https://github.com/quartznet/quartznet/pull/3013
* Store auto-pin as a flag column instead of an "auto:" name prefix by @​lahma in https://github.com/quartznet/quartznet/pull/3144
* Clamp misfire handler and cluster manager sleeps after system clock jumps (#​1508) by @​lahma in https://github.com/quartznet/quartznet/pull/3147
* Update packages and cleanup by @​lahma in https://github.com/quartznet/quartznet/pull/3151
* Migrate the build from NUKE to Fallout (3.x) by @​lahma in https://github.com/quartznet/quartznet/pull/3163
* Exclude the build orchestrator from SonarQube analysis (3.x) by @​lahma in https://github.com/quartznet/quartznet/pull/3166
* Prepare v3.19.0 release by @​lahma in https://github.com/quartznet/quartznet/pull/3169


**Full Changelog**: https://github.com/quartznet/quartznet/compare/v3.18.2...v3.19.0


Commits viewable in [compare view](https://github.com/quartznet/quartznet/compare/v3.18.2...v3.19.1).
</details>

Updated [Quartz.Serialization.SystemTextJson](https://github.com/quartznet/quartznet) from 3.18.2 to 3.19.1.

<details>
<summary>Release notes</summary>

_Sourced from [Quartz.Serialization.SystemTextJson's releases](https://github.com/quartznet/quartznet/releases)._

## 3.19.1

Quartz.NET 3.19.1 is a small bug fix release with two targeted fixes: `DailyTimeIntervalTrigger` no longer gets stuck in an infinite fire loop on DST spring-forward days, and `StdSchedulerFactory.GetScheduler(schedName)` now creates the scheduler when the name asked for is its own. There are no API or schema changes, so it is a drop-in upgrade from 3.19.0.

## Highlights

- **`DailyTimeIntervalTrigger` no longer spins on DST transition days** — `GetFireTimeAfter` could return a time at or before the one it was given, which makes `QuartzSchedulerThread` fire the trigger, compute the same next fire time, and fire again — pinning a CPU core and flooding the log. Two independent causes, both on a spring-forward day: the DST correction added for #​1114 was applied to every interval size and in either direction (so every interval of an hour or less was affected, in every DST time zone), and the daily rollover to `StartTimeOfDay` reused whatever UTC offset the previous fire time carried (so in time zones that move the clock at midnight, such as Chile, `StartTimeOfDay` 00:00 resolved to an instant *before* the transition — the same instant that was passed in). Verified across 3024 combinations of 12 time zones, both transitions, 21 intervals and 6 start times: 468 combinations produced non-advancing fire times before, none do now. (#​3190, fixes #​332)
  - **Behavior change worth noting:** the same fix stops sub-hour triggers silently dropping the last hour of a **fall-back** day. A 5-minute trigger now fires 300 times through the 25-hour day, ending at 23:55 local, instead of 288 times ending at 22:55.
- **`StdSchedulerFactory.GetScheduler(schedName)` creates its own scheduler** — asking a factory for the scheduler it is configured to produce returned `null` until somebody had called `GetScheduler()` first. It now creates it. Any other name stays a pure lookup, so probing for a scheduler somebody else owns still has no side effects, and the name comparison is case-insensitive to match how `SchedulerRepository` indexes names. The DI factory has behaved this way since #​2845; this brings the property-configured factory in line. (#​3188, reported in #​2786, originally proposed in #​360)

## What's Changed
* Create the scheduler when it is looked up by its own name (#​360) by @​lahma in https://github.com/quartznet/quartznet/pull/3188
* Fix DailyTimeIntervalTrigger infinite fire loop during DST spring-forward (#​332) by @​lahma in https://github.com/quartznet/quartznet/pull/3190


**Full Changelog**: https://github.com/quartznet/quartznet/compare/v3.19.0...v3.19.1


## 3.19.0

Quartz.NET 3.19.0 is a feature release: it adds node affinity for clustered scheduling, a fluent cron-expression builder, and richer `L`/`LW` day-of-month expressions, plus clock-jump resilience and a modernized build and publishing pipeline. The public API is unchanged (all additions are additive), so it is a drop-in upgrade — with two things to note: the new node-affinity columns are an **optional** schema migration (the feature degrades gracefully without them), and a handful of previously-broken `L`/`LW`/`W` cron expressions now fire correctly (see below).

## Highlights

- **Node affinity for clustered trigger pinning** — pin a trigger to a preferred node with `TriggerBuilder.WithPreferredNode(...)`; the node is preferred for acquisition but the trigger is still stolen on failover so it is never stranded if that node goes down. Adds optional `PREFERRED_NODE` / `PREFERRED_NODE_AUTO` columns for ADO.NET job stores (`database/schema_30_add_preferred_node.sql`); when the columns are absent the scheduler logs a warning and behaves exactly as before. (#​3013, #​3144)
- **Fluent `CronExpressionBuilder`** — compose cron expressions programmatically, one field at a time, instead of hand-writing the string — handy when a schedule is assembled from user input such as a scheduling UI. (#​3139)
- **`L` and `LW` combinable with other day-of-month values** — the day-of-month field now accepts expressions such as `1,15,L` and the new `LW-n` / `L-nW` grammar. This also corrects several previously-buggy edge cases: `29W`/`31W` no longer silently skip short months, `L-30W` no longer throws mid-schedule, and `1,15W` now applies `W` to each day rather than only the first. **These corrections change the fire times of a few expressions that were previously broken** — review any stored `L`/`LW`/`W` day-of-month expressions. (#​2759)
- **Resilience to system clock jumps** — the misfire handler and cluster manager now clamp their sleep intervals after the system clock jumps forward or backward, so a clock step no longer causes a busy-spin or an absurdly long sleep. (#​3147, fixes #​1508)
- **Modernized build & publishing** — the build orchestrator moved from the unmaintained NUKE to Fallout (#​3163), and packages now publish to nuget.org via GitHub OIDC **trusted publishing** rather than a stored API key. Dependencies were also refreshed (#​3151).

**Note for `CronScheduleBuilder` users:** `AtHourAndMinuteOnGivenDaysOfWeek` / `WeeklyOnDayAndHourAndMinute` now emit textual day-of-week names (e.g. `MON,WED` rather than `2,4`). The schedules are identical, but the generated `CRON_EXPRESSION` string differs — relevant only if you compare stored cron strings byte-for-byte.

## What's Changed
* Serve Blazor plumbing under custom DashboardPath for prefix-forwarding reverse proxies (3.x) (#​3134) by @​lahma in https://github.com/quartznet/quartznet/pull/3137
* Add fluent CronExpressionBuilder for building cron expressions programmatically (3.x) by @​lahma in https://github.com/quartznet/quartznet/pull/3139
* Support for specifying 'L' and 'LW' with other days in day-of-month field by @​lahma in https://github.com/quartznet/quartznet/pull/2759
* Add preferred node (node affinity) for cluster trigger pinning by @​lahma in https://github.com/quartznet/quartznet/pull/3013
* Store auto-pin as a flag column instead of an "auto:" name prefix by @​lahma in https://github.com/quartznet/quartznet/pull/3144
* Clamp misfire handler and cluster manager sleeps after system clock jumps (#​1508) by @​lahma in https://github.com/quartznet/quartznet/pull/3147
* Update packages and cleanup by @​lahma in https://github.com/quartznet/quartznet/pull/3151
* Migrate the build from NUKE to Fallout (3.x) by @​lahma in https://github.com/quartznet/quartznet/pull/3163
* Exclude the build orchestrator from SonarQube analysis (3.x) by @​lahma in https://github.com/quartznet/quartznet/pull/3166
* Prepare v3.19.0 release by @​lahma in https://github.com/quartznet/quartznet/pull/3169


**Full Changelog**: https://github.com/quartznet/quartznet/compare/v3.18.2...v3.19.0


Commits viewable in [compare view](https://github.com/quartznet/quartznet/compare/v3.18.2...v3.19.1).
</details>

Updated [Radzen.Blazor](https://github.com/radzenhq/radzen-blazor) from 11.1.7 to 11.2.2.

<details>
<summary>Release notes</summary>

_Sourced from [Radzen.Blazor's releases](https://github.com/radzenhq/radzen-blazor/releases)._

## 11.2.2

# 11.2.2 - 2026-08-04

### Improvements
- **RadzenDropDown**, **RadzenListBox** and **RadzenDropDownDataGrid** - Ctrl+A now selects all items in multiple selection when `AllowSelectAll` is enabled - press again to clear the selection. The shortcut is documented in the Keyboard Navigation section of each component.

### Fixes
- **RadzenDropDown** and **RadzenDropDownDataGrid** - the popup no longer flickers when clicking a component with `OpenOnFocus` and no longer reopens when clicking outside of it. Clicking the component while its popup is open now closes it. Fixes #​2640
- **RadzenDataGrid** - self-reference hierarchy view no longer degrades to O(n²) per enumeration - grids with tens of thousands of rows render instantly instead of taking seconds. Fixes #​2637
- **RadzenDataGrid** - custom column filter expressions are now applied even when no other filters are active (#​2639).
- **RadzenSpreadsheet** - opening xlsx files with shared formulas no longer fails - `XlsxReader` and `XlsxWriter` now support them. Fixes #​2638


## 11.2.1

# 11.2.1 - 2026-08-03

### Improvements
- **RadzenSpreadsheet** - copy and cut now highlight the source cell range with an animated marching ants marquee (#​2625).
- **RadzenDatePicker** - now passes its `InputSize` to the calendar inputs - Month and Year drop downs and Hour, Minutes and Seconds numerics.

### Fixes
- **RadzenCarousel** - pages align correctly when `ItemsPerPage` is an even number - middle pages no longer show neighboring items cut in half and the pager no longer jumps back after navigation.

## 11.2.0

# 11.2.0 - 2026-07-30

### Fixes
- **RadzenUpload** - no longer throws `NullReferenceException` in `OnAfterRenderAsync` when re-rendered or disposed while its JS handlers are being recreated, and no longer raises `Complete` twice for a single upload. Fixes #​2635.
- **RadzenDataGrid, RadzenDatePicker, RadzenDropDown, RadzenFileInput** - no longer leak a .NET JS interop proxy every time their JS handlers are recreated.
- **RadzenAccordion, RadzenAutoComplete, RadzenCarousel, RadzenFormField, RadzenGoogleMap, RadzenHtmlEditor, RadzenMask, RadzenMenu, RadzenNumeric, RadzenProfileMenu, RadzenSecurityCode, RadzenSignaturePad, RadzenSlider, RadzenSplitButton** - protected against the same JS handler race that could throw `NullReferenceException` or attach duplicate JS event handlers.

## 11.1.8

# 11.1.8 - 2026-07-27

### Fixes
- **RadzenTextBox, RadzenTextArea, RadzenMask, RadzenPassword, RadzenAutoComplete** - bound inputs no longer reset their displayed value when used inside a `RenderFragment` created by another component - most commonly inline dialog content passed to `DialogService.OpenAsync`. Such fragments never re-flow parameters, so the component kept a stale value and wiped the typed text from the input on blur while the bound variable kept it. The local value assignment is now unconditional, matching Blazor's own `InputBase` behavior.
- **Popups** - popups no longer get permanently stuck open when the closing animation never runs or is canceled - e.g. app-level CSS such as reduced-motion resets with `animation: none`. Closing now hides the popup immediately when no close animation is actually running, and the `ClosePopup()` API reliably recovers a stuck popup. Fixes #​2601.
- **RadzenDialog** - opening a nested dialog no longer breaks resize and drag handling of the outer dialog. Each dialog now has its own resize observer and titlebar drag handler instead of sharing a single global slot. Thanks to @​I-Info!
- **RadzenUpload** - the `Method` and `Stream` parameters are now honored when uploading via the `Upload()` method with `Auto=false`. The manual upload path always sent a POST multipart request regardless of the configured method.


Commits viewable in [compare view](https://github.com/radzenhq/radzen-blazor/compare/v11.1.7...v11.2.2).
</details>

Updated [WolverineFx.Marten](http://github.com/jasperfx/wolverine) from 6.22.0 to 6.25.0.

<details>
<summary>Release notes</summary>

_Sourced from [WolverineFx.Marten's releases](http://github.com/jasperfx/wolverine/releases)._

## 6.25.0

Couple bugs, one new API meant for CritterWatch

## What's Changed
* #​3867 a batched handler participates in partitioned sequential processing by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3868
* #​3869: latch endpoint-originated causation reporting by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3872
* GlobalPartitionedMessageTopology.Except<T>() (#​3867 follow-up) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3873
* #​3871: apply endpoint policies to broker system endpoints by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3874
* #​3870: route the durable inbox to a handler's enrolled DbContext store by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3875
* #​3871 follow-up: narrow the system endpoint compile to Rabbit MQ by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3876


**Full Changelog**: https://github.com/JasperFx/wolverine/compare/V6.24.10...V6.25.0

## 6.24.10

Small bug fix release: queue endpoints addressed only by Uri on the database-backed transports (SQL Server, PostgreSQL, SQLite, MySQL) now sanitize the queue name the same way the fluent API does, so a name like `sqlserver://my-service-control` no longer produces invalid `wolverine_queue_*` table DDL from the dash. This was uncovered by CritterWatch's `systemControlUri` usage in the field.

## What's Changed
* Database queue Uris sanitize the queue name like the fluent API does by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3865


**Full Changelog**: https://github.com/JasperFx/wolverine/compare/V6.24.9...V6.24.10

## 6.24.9

This is mostly about CritterWatch uncovered issues with very high volumes of messaging via SQS and making the back pressure detection a bit more sophisticated

## What's Changed
* Batching pipelines: back-pressure sees their depth, faulted receivers rebuild, OOM can't fault the block (CritterWatch#​942) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3864


**Full Changelog**: https://github.com/JasperFx/wolverine/compare/V6.24.8...V6.24.9

## 6.24.8

Bug fix release. Four durability and multi-tenancy fixes, all with regression coverage.

## Fixes

**[#​3856](https://github.com/JasperFx/wolverine/issues/3856) — Dormant inbox rows for a durable local queue were never recovered** ([#​3857](https://github.com/JasperFx/wolverine/pull/3857))
`PublishToPartitionedLocalMessaging()` marks every slot `ListenerScope.Exclusive`, and the GH-3590 carve-out then handed inbox recovery to a loop that is never constructed for a local queue — a local queue never gets a `ListeningAgent` at all. Envelopes sat at `status='Incoming'`, `owner_id=0` indefinitely, surviving rolling deploys. Both guards implementing that hand-off now ask a single `Endpoint.IsSingleNodeListener` predicate, which `LocalQueue` answers `false`. Reported by @​erdtsieck.

**[#​3815](https://github.com/JasperFx/wolverine/issues/3815) — `forEveryDatabase` visited the main database twice** ([#​3858](https://github.com/JasperFx/wolverine/pull/3858))
`MultiTenantedMessageStore.ActiveDatabases()` yields `Main` first, so on any multi-tenanted configuration the Oracle, PostgreSQL and MySQL queues counted the main database twice — `GetAttributesAsync()` reported a queue depth of 2 for a single row. Schema checks and purges also ran twice. SqlServer and Sqlite were already correct.

**[#​3859](https://github.com/JasperFx/wolverine/issues/3859) — MySQL multi-tenanted queues shared one physical table** ([#​3861](https://github.com/JasperFx/wolverine/pull/3861))
A MySQL schema *is* a database, so the single `TransportSchemaName` resolved every tenant to the same queue table: no isolation, and counts that multiplied by the tenant count instead of summing. Queue tables now resolve inside each tenant's own database. Single-database hosts are unaffected.

**[#​3860](https://github.com/JasperFx/wolverine/issues/3860) — MySQL database-per-tenant storage had no isolation** ([#​3862](https://github.com/JasperFx/wolverine/pull/3862))
The same root cause in the message stores: every tenant store received the one configured schema name, so inbox, outbox, dead letter, node and saga tables were shared across all tenants. Each tenant's database is now its own schema.

## Upgrading

**MySQL database-per-tenant users only.** Before this release your tenant envelope rows all lived in the single configured schema. After upgrading, each tenant reads from its own database instead — drain or copy across any in-flight envelopes still sitting in the old shared tables before you upgrade. No other provider or configuration is affected.

**Full changelog**: https://github.com/JasperFx/wolverine/compare/V6.24.7...V6.24.8


## 6.24.7

This is a fix release. Its centre of gravity is agent assignment: a leader that re-decided the same placements every cycle, and — hidden underneath that churn — a serial stop path that made every rebalance far slower than it needed to be.

## Agent assignment converges much faster

**[#​3852](https://github.com/JasperFx/wolverine/issues/3852) — the leader re-decided placements it had already made.** The GH-3698 pending-assignment ledger armed on a `ReassignAgent` but could never apply one: an agent being moved is still listed in its *source* node's persisted `ActiveAgents`, so the guard that skips agents with a known original node skipped every reassignment. GH-3698 closed this hole for first-time placement and left it open for moves.

On a 512-database / 5-node / ~8,700-agent cluster that reproduced as **3,468 decisions every cycle against a frozen snapshot, indefinitely** — matching the ~45,000 decisions over six minutes reported from production. It converged in spite of itself, because the batched command carries set-based value equality and the dispatcher collapses an identical re-emitted batch while its lane is busy, so it read as benign. The telemetry was not deduplicated at all: `AssignmentsChanged` fires before batching, so every one of those decisions wrote an `AssignmentChanged` node record.

**The churn was concealing a second defect.** `StartAgents` got bounded parallelism back in GH-3604 — a 50-agent chunk started one at a time was seconds of dead wall-clock that blew the reply window. The stop side is the same shape and never got it: a plain `foreach`, so at `AgentStartBatchSize = 50` an entire chunk's stop cost ran in series before a single start could cascade. It survived only because the per-cycle churn was trickling agents onto the destination alongside the batch. Fixing the churn exposed it.

Measured against the 512-database reproduction:

| | 6.24.6 | ledger fix only | **6.24.7** |
|---|---|---|---|
| work reaching fresh nodes | 38.0s | 74.1s | **14.0s** |
| full convergence | 176.3s | 176.3s | **31.1s** |

Net **5.7x faster to converge** than 6.24.6, not merely quieter.

**[#​3850](https://github.com/JasperFx/wolverine/issues/3850)** — the cached node-number release is now bounded by a high-water mark, so a newcomer's messages cannot be released by a stale cache. Follow-up to GH-3846.

**Node-number lookups happen once per node instead of once per database** ([#​3847](https://github.com/JasperFx/wolverine/pull/3847), thanks **@​erdtsieck**) — a real saving on multi-database deployments, where the old shape scaled with the shard count.

## Durability/projection affinity now reports whether it engaged

[#​3785](https://github.com/JasperFx/wolverine/issues/3785) shipped in 6.24.5: a shard database's durability agent follows that database's event-subscription agents, so the database attracts one node's connection pool instead of two.

That join is deliberately fail-silent — a miss falls back to the even spread, because a miss is never *wrong*, only not-better. The problem is diagnostic: **a join that never fires because the two descriptor pipelines spell the same database differently looks exactly like the feature working, minus the benefit.** Verifying it meant joining `pg_stat_activity` against the assignment table on a live cluster.

It now says so directly, once, when the numbers change:

Durability/projection database affinity (GH-3785) co-located 446 of 446 durability agents
with their database's event subscription agents across 446 databases


and escalates to a **warning** in the one unambiguous case — projection agents present, database-bearing durability agents present, zero matched. On a multi-database store that is a spelling divergence, not a coincidence. An application with no projections has nothing to follow and stays quiet.

## Transport and listener fixes

**[#​3832](https://github.com/JasperFx/wolverine/issues/3832)** — a deliberately paused listener now reports the distinct `ListeningStatus.Paused` instead of being indistinguishable from back-pressure `TooBusy`. The contract now matches what the code actually does.

**[#​3842](https://github.com/JasperFx/wolverine/issues/3842)** — `RabbitMqListener.CreateAsync` no longer dereferences a null `Channel` when the agent is disposed mid-startup.

## Testing and build

- **[#​3799](https://github.com/JasperFx/wolverine/issues/3799)** — Pulsar tests share one digest-pinned broker per job rather than starting a heavy container per worker process on an unpinned `:latest`, which used to hang silently when Docker ran out of memory.
- **[#​3800](https://github.com/JasperFx/wolverine/issues/3800)** — the CloudEvents compliance harness carries an exception *type name* rather than an `Exception`, so dead-lettering by exception type can actually be tested; `ErrorCausingMessage` never round-tripped through System.Text.Json.
- **[#​3839](https://github.com/JasperFx/wolverine/issues/3839) / [#​3841](https://github.com/JasperFx/wolverine/issues/3841)** — the solution builds every project, including two shipping packages that previously compiled only during `Pack`, and the Polecat incident-service sample (whose tests had not compiled since April, with nothing noticing).

 ... (truncated)

## 6.24.6

A bug-fix release. The headline is a **message ordering regression** affecting every transport built on `BatchedSender` — if you rely on FIFO ordering anywhere, this release matters to you.

## Highlights

**Message ordering restored in `BatchedSender`** ([#​3825](https://github.com/JasperFx/wolverine/issues/3825)). `BatchedSender` ran its serializing stage at `Environment.ProcessorCount`, so envelopes reached the batching block in *serialization-completion* order rather than enqueue order.

This was a silent regression from the switch off TPL Dataflow. `ActionBlock` defaults `MaxDegreeOfParallelism` to **1** — ordered by default — and the Channels rewrite raised it without the ordering guarantee being restated anywhere. The block was ordered for years, then quietly wasn't. The practical effect: **FIFO ordering was not honored** under Azure Service Bus sessions, SQS FIFO message groups, or global partitioning, on every transport that uses `BatchedSender`. Nothing was lost; messages arrived out of order. Fixed by returning the stage to a degree of parallelism of 1 — everything downstream was already serial.

A second, independent defect fell out of the same investigation: `TrackedSession.AllRecordsInOrder()` sorted by `SessionTime`, which is `ElapsedMilliseconds` — whole milliseconds. An entire receive batch ties, and the stable sort then fell back to enumerating a Guid-keyed cache with no relation to real order. **Every ordering assertion in the test suite was at the mercy of this.** Records now carry a monotonic sequence number.

**Back-pressure now works on the right number, and says what it is** ([#​3831](https://github.com/JasperFx/wolverine/pull/3831), [jasperfx#​632](https://github.com/JasperFx/jasperfx/pull/632)). A latched listener logged exactly one `too busy` line and then nothing — forever. An operator watching a queue grow for 40 minutes could not distinguish "still draining" from "wedged". Underneath that, the count a `PartitionProcessingByGroupId` endpoint latched *and resumed* against was wrong: the downstream block holding the backlog was invisible to it, so `Count` reported zero for work that was really there.

* `BackPressureAgent` logs a periodic warning while a listener stays latched, carrying the queue count and the restart threshold the resume decision is made from.
* The timer-driven check is exception-safe. A throw during an attempted resume was an unobserved `ValueTask` fault, and the listener silently never resumed.
* `BufferedReceiver`/`DurableReceiver` wire the receiving block's `OnError` to `ILogger`. A terminally-faulted block freezes the queue count and permanently latches the listener; that now logs at Critical instead of vanishing to stderr.

**A tenanted Azure Service Bus endpoint could not send at all** ([#​3826](https://github.com/JasperFx/wolverine/issues/3826)) — tenanted or untenanted. `TenantedSender` deliberately does not implement `ISenderRequiresCallback`, but callback registration did not recurse, so a `BatchedSender` underneath it kept a null callback and threw `InvalidOperationException: This sender has not been registered.` on every batch. The tenanted path now uses inline senders, matching how Redis, MQTT, and Pub/Sub already worked around this.

**Oracle queue identity round-trip** ([#​3820](https://github.com/JasperFx/wolverine/issues/3820)). `System.Uri` lowercases the authority component while Oracle uppercases its queue identifiers, so `ToOracleQueue()` resolved a *second* endpoint over the same physical tables. Also fixes a dead final-attempt error handler: a `when` clause that included the loop counter made the descriptive exception at the bottom of the retry loop unreachable.

## Behavior change worth reading

**`TrackedSession` now completes only when *all* conditions are satisfied, not the first** ([#​3824](https://github.com/JasperFx/wolverine/issues/3824)). This is a public testing API. A tracked session configured with several expectations previously returned as soon as any one of them was met, which means some existing tests were passing vacuously. After upgrading, such a test waits for every condition — and may now fail where it previously passed. That failure is generally revealing a real gap rather than introducing one.

## Other changes

* **JasperFx upgraded to 2.39.5.** Beyond the block `Count` fix above, this carries [jasperfx#​600](https://github.com/JasperFx/jasperfx/issues/600)/[#​601](https://github.com/JasperFx/jasperfx/issues/601) — the application-assembly stack walk could adopt a test-runner assembly and then scan an assembly holding none of your types — and [jasperfx#​599](https://github.com/JasperFx/jasperfx/issues/599), where `DatabaseId`'s escaping now survives a `System.Uri` round trip.
* `EventSubscriptionAgentFamily.DatabaseKeyOf` and `TenantNeutralKeyOf` are now public ([#​3819](https://github.com/JasperFx/wolverine/issues/3819)).

## Testing and CI

No runtime behavior changes here, but this is why the fixes above became findable. The `Category=Flaky` exclusion list went from 12 tagged classes to **zero** ([#​3763](https://github.com/JasperFx/wolverine/issues/3763)) — and several of those tags turned out to have been added in the very commit that introduced the feature they test, hiding working code rather than broken code. Every CI readiness gate now fails loudly instead of warning and continuing; the Kafka gate in particular was a no-op that passed in 0.0s against a broker that would not serve metadata for another 3 seconds ([#​3814](https://github.com/JasperFx/wolverine/issues/3814)). The retry ledger records *why* a test flaked rather than only which one ([#​3787](https://github.com/JasperFx/wolverine/issues/3787)), and `CIAzureServiceBus` was sharded three ways on measured per-class durations ([#​3790](https://github.com/JasperFx/wolverine/issues/3790)).

## What's Changed

* Retry `docker compose up` so a registry timeout does not redden main by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3807
* Oracle clear_all: clean the schema the queue tables are actually in (GH-3763) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3808
* Bug_2518: stop asserting exclusivity on the lock every migration takes (GH-3763) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3809
* Retry ledger: record WHY a flaky test failed, not just which one (GH-3787) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3810
* Retry ledger: record the failing attempt's stack, not just its message (GH-3763) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3811
* Record the MQTT Broken pipe flake as accepted retry debt (GH-3763) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3812
* Make every readiness gate fatal, and pin the images that still rolled (GH-3763) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3813
* Shard CIAzureServiceBus three ways on measured per-class durations (GH-3790) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3818
* Fix two test-side races behind the CISqlServer retries (GH-3821) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3822
* Fix the Oracle queue Uri identity round-trip, and finish GH-3808 (GH-3820) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3823
* Complete a tracked session only when ALL conditions are satisfied (GH-3824) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3828
* Make EventSubscriptionAgentFamily.DatabaseKeyOf and TenantNeutralKeyOf public (GH-3819) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3829
* Assert on the queue name, not the endpoint name, and untag Bug_2307 (GH-3827) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3830
* Back-pressure observability: a latched listener says so, and block errors reach real logging by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3831
* Use inline senders on the tenanted Azure Service Bus path (GH-3826) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3833
 ... (truncated)

## 6.24.5

> Note: 6.24.4 shipped on NuGet without a GitHub release, so these notes cover everything since V6.24.3.

## Highlights

**Multi-database projection & subscription assignment got a major reliability pass.** For sharded event stores, Wolverine assigns the agents for projections and subscriptions in groups by database — so connection pools scale with the number of databases rather than nodes × databases:

* A blue/green rollout carrying a **projection version bump** no longer assigns the new version's agents to nodes that cannot build them — previously the new version could never start anywhere for the whole rollout ([#​3792](https://github.com/JasperFx/wolverine/pull/3792), thanks @​erdtsieck). A split database now costs exactly one owner per version.
* **Database affinity is now a property of the database across agent families** ([#​3785](https://github.com/JasperFx/wolverine/issues/3785)): a shard database's durability agent follows that database's projection agents onto the same node, so the database attracts one node's connection pool instead of two. Measured on a 512-database production cluster, 73% of databases were split across two nodes, wasting ~425 connection slots. Expect a one-time wave of durability-agent reassignments on first deploy as an existing cluster converges.
* The settled assignment state is now pinned as a **fixed point** — re-evaluating a converged cluster moves nothing — and a new deterministic simulation drives the real leader evaluation through the exact deploy shape of GH-3753: slow agent starts *and* a blue/green capability split at once.

**Durable outbox to SNS/SQS FIFO destinations is fixed** ([#​3793](https://github.com/JasperFx/wolverine/issues/3793)): `EnvelopeSerializer` never round-tripped `Envelope.DeduplicationId`, so any envelope recovered from durable storage after an outage was re-sent without `MessageDeduplicationId` and rejected deterministically by a FIFO destination without content-based deduplication — retrying forever or dead-lettering. Also fixed alongside it: the circuit-resume ping could never reach a FIFO destination (a latched sender could never unlatch), and SNS sent `MessageDeduplicationId` to standard topics, which AWS rejects. The same fix is merged to the 5.x maintenance branch and will ship in the next 5.40.x release for .NET 8 users.

**Balanced-mode host shutdown no longer hangs** ([#​3781](https://github.com/JasperFx/wolverine/issues/3781)): stopping a node while agent commands were queued could pay a full agent-batch reply window per queued command — measured at 17+ minutes. Now ~2 minutes on the same reproduction.

**Azure Service Bus conventional routing sanitizes entity names** ([#​3786](https://github.com/JasperFx/wolverine/issues/3786)): a handler for an array message type (e.g. `Handle(Foo[])`) produced an illegal ASB entity name that broke broker startup for the whole assembly, and the real reason was lost. Names are sanitized and failures now carry the offending name.

## What's Changed

* Never adopt a test-runner assembly as the application assembly (GH-3776) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3777
* CI/testing sweep: compliance assertion scoping, Marten segmentation, dispose leaks by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3775
* GH-3779: a dev-scale reproduction of slow agent starts, and the first flaky-tag burn-down (GH-3763) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3780
* Stop Balanced-mode host shutdown paying a full agent reply window (GH-3781) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3782
* Wait for the ASB emulator's management api, and pin the image by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3783
* Restore 32 Azure Service Bus tests, re-tag 11 that are genuinely broken (GH-3763, GH-3786) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3784
* Report what every CI job spends of its retry budget (GH-3787) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3788
* Sanitize Azure Service Bus entity names, and stop losing the reason (GH-3786) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3789
* Point the AWS tests at LocalStack, and fix the SQS name limit they were hiding (GH-3763) by @​jeremydmiller in https://github.com/JasperFx/wolverine/pull/3791
* Restore the Kafka tests the Flaky tag was hiding (GH-3763) by @​jeremydm...

_Description has been truncated_

Bumps AndreGoepel.Core from 1.0.0 to 1.0.1
Bumps AndreGoepel.Marten.Identity.Blazor from 1.8.0 to 1.9.1
Bumps bunit from 2.8.6 to 2.9.0
Bumps Marten from 9.19.0 to 9.22.5
Bumps Npgsql from 9.0.4 to 9.0.5
Bumps Quartz.Extensions.Hosting from 3.18.2 to 3.19.1
Bumps Quartz.Serialization.SystemTextJson from 3.18.2 to 3.19.1
Bumps Radzen.Blazor from 11.1.7 to 11.2.2
Bumps WolverineFx.Marten from 6.22.0 to 6.25.0
Bumps WolverineFx.RuntimeCompilation from 6.22.0 to 6.25.0

---
updated-dependencies:
- dependency-name: AndreGoepel.Core
  dependency-version: 1.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget-minor-patch
- dependency-name: AndreGoepel.Marten.Identity.Blazor
  dependency-version: 1.9.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: bunit
  dependency-version: 2.9.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Marten
  dependency-version: 9.22.5
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Npgsql
  dependency-version: 9.0.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: nuget-minor-patch
- dependency-name: Quartz.Extensions.Hosting
  dependency-version: 3.19.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Quartz.Serialization.SystemTextJson
  dependency-version: 3.19.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: Radzen.Blazor
  dependency-version: 11.2.2
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: WolverineFx.Marten
  dependency-version: 6.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
- dependency-name: WolverineFx.RuntimeCompilation
  dependency-version: 6.25.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: nuget-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added .NET Pull requests that update .NET code dependencies Pull requests that update a dependency file labels Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file .NET Pull requests that update .NET code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants