Skip to content

Recover ambiguous DCP creates with configurable timeouts - #20752

Merged
David Negstad (danegsta) merged 2 commits into
mainfrom
danegsta-dcp-watch-timeouts
Oct 10, 2026
Merged

David Negstad (danegsta) merged 2 commits into
mainfrom
danegsta-dcp-watch-timeouts

Conversation

@danegsta

Copy link
Copy Markdown
Member

Description

A single timed-out or HTTP 504 DCP create currently puts a resource into FailedToStart, even though the server may have committed the object. The 20-second steady-state client budget can also expire before DCP's own create timeout, and users cannot configure those limits for slower environments.

Recover ambiguous creates by checking whether the same kind/namespace/name exists before retrying the POST. Creation has a configurable two-minute recovery budget covering setup, requests, confirmation, and retry delays. Initial conflicts and permanent failures still fail, caller cancellation remains terminal, and successful sibling creates are not replayed.

API operations now share one deadline between client setup and the request/retry work: 40 seconds plus a 20-second initialization allowance until the first successful API operation, then 40 seconds. Each operation selects its deadline once. Watch reconnects reselect the current budget without shortening in-flight requests or limiting established watch/log streams.

KubernetesClient's independent 100-second request timer no longer truncates larger configured budgets. Production requests use Aspire's timeout policy, including the cleanup polling GET that previously bypassed it. No new dependencies are required.

Fixes #20691

User-facing usage

The default timeout settings can now be overridden in AppHost configuration:

{
  "DcpPublisher": {
    "KubernetesApiTimeout": "00:00:40",
    "KubernetesInitializationAdditionalTimeout": "00:00:20",
    "KubernetesCreateRecoveryTimeout": "00:02:00"
  }
}

The initialization allowance may be zero. API and recovery budgets support one second through ten minutes; the API budget plus initialization allowance must not exceed ten minutes.

Validation

Passed: 97 selected tests, with no failures or skips. Coverage includes ambiguous-create confirmation/retries, permanent failures, caller cancellation, configuration validation, readiness-aware deadlines, watch reconnects, and established stream lifetimes.

MSBUILDTERMINALLOGGER=false ./dotnet.sh test \
  --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj \
  --no-launch-profile --no-restore /p:SkipNativeBuild=true \
  -- \
  --filter-class '*.KubernetesServiceTests' \
  --filter-class '*.ConfigureDefaultDcpOptionsTests' \
  --filter-not-trait 'quarantined=true' \
  --filter-not-trait 'outerloop=true'

No live DCP reproduction, end-to-end validation, or full test-suite run was performed for the final changes.

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Confirm timed-out creates before retrying the same named object, bound create recovery, and share readiness-aware request deadlines across client setup and API operations.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 20752

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 20752"

@aspire-repo-bot
aspire-repo-bot Bot requested a balanced review from Copilot October 6, 2026 01:28
@github-actions github-actions Bot added the needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners label Oct 6, 2026
@github-actions

This comment has been minimized.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The cross-cutting retry and timeout lifecycle changes lack live DCP or end-to-end validation.

Review effort: Balanced
Findings: None

What changed in this PR

Adds resilient DCP object creation and configurable Kubernetes API deadlines for slow environments.

Changes:

  • Reconciles ambiguous creates before retrying.
  • Adds validated API, initialization, and recovery timeout settings.
  • Applies Aspire deadlines consistently while preserving established streams.
File Description
src/​Aspire.Hosting/​Dcp/​KubernetesService.cs Implements recovery and shared deadline policies.
src/​Aspire.Hosting/​Dcp/​DcpOptions.cs Adds timeout configuration and validation.
src/​Aspire.Hosting/​Dcp/​DcpKubernetesClient.cs Disables the SDK’s independent timeout.
tests/​Aspire.Hosting.Tests/​Dcp/​KubernetesServiceTests.cs Covers recovery, deadlines, cancellation, and streams.
tests/​Aspire.Hosting.Tests/​Dcp/​ConfigureDefaultDcpOptionsTests.cs Covers defaults, configuration, and validation.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@danegsta

David Negstad (danegsta) commented Oct 6, 2026 •

Copy link
Copy Markdown
Member Author

PR Testing Report

PR Information

  • PR: #20752 - Recover ambiguous DCP creates with configurable timeouts
  • Head commit: 065920e94144388c046f4f5daf18db02e5ff3dbd
  • Tested at: 2026-10-06, completed at approximately 17:56 UTC
  • Execution: Repository container runner, Docker Desktop desktop-linux, Ubuntu 24.04 / Linux ARM64
  • Source regressions: macOS ARM64, Microsoft.Testing.Platform, net8.0
  • Repository changes made during testing: None

Artifact Version Verification

  • Installed CLI: 17.0.0-pr.20752.g065920e9
  • CLI path: /workspace/.aspire/dogfood/pr-20752/bin/aspire
  • PR package hive: /workspace/.aspire/hives/pr-20752/packages
  • Loaded Hosting assembly informational version: 17.0.0-pr.20752.g065920e9
  • Hosting package repository commit: c3ce52cb73d52b1e689113563b2eec7cb6c1b907
  • Status: Verified.

The package repository commit is the normal CI merge commit. Its parents are base
833be629720d582a57118babf1423201aa4944e9 and the exact PR head
065920e94144388c046f4f5daf18db02e5ff3dbd. This was checked against GitHub's commit
API; it is not a stale package mismatch. The running AppHost printed its loaded
Hosting assembly version, rather than relying only on the CLI's version.

The Tests workflow
also reports the same PR head and completed successfully. At the initial check,
the PR had 282 successful checks, 15 skipped checks, and no failed or pending
checks. The 153 check names matching Hosting.Tests or E2E all succeeded.

Changes Analyzed

Files Changed

  • src/Aspire.Hosting/Dcp/DcpKubernetesClient.cs: Remove the independent KubernetesClient request timer.
  • src/Aspire.Hosting/Dcp/DcpOptions.cs: Configurable API, additional initialization, and create-recovery budgets.
  • src/Aspire.Hosting/Dcp/KubernetesService.cs: Ambiguous-create confirmation/retry and readiness-aware operation deadlines.
  • tests/Aspire.Hosting.Tests/Dcp/ConfigureDefaultDcpOptionsTests.cs: Configuration and boundary regressions.
  • tests/Aspire.Hosting.Tests/Dcp/KubernetesServiceTests.cs: HTTP-backed recovery, cancellation, readiness, and stream-lifetime regressions.

Change Categories

  • Hosting core
  • Tests
  • CLI
  • Dashboard
  • Templates
  • Client integrations
  • VS Code extension
  • CI infrastructure

Environment Setup and Exact Commands

All five scenario apps were freshly generated with aspire new, in a temporary
workspace outside the repository. No automated repository E2E suite was run
locally; its validation remains in CI.

Host runner prefix, with testDir set to the recorded temporary workspace:

ASPIRE_PR_WORKSPACE="$testDir" ASPIRE_CONTAINER_USER=0:0 \
  ./eng/scripts/aspire-pr-container/run-aspire-pr-container.sh <command>

Inside the runner, installation used the PR's published dogfood command:

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh \
  | bash -s -- 20752

Result: Passed. The installer selected workflow run 37399355709, downloaded
the common and Linux ARM64 artifacts, and installed the expected CLI and package
hive. VS Code installation was skipped because code is not installed; this PR
has no extension changes.

Resolved prerequisite failure

The first normal AppHost start failed before DCP launched:

C# AppHost requires .NET SDK version 10.0.100 or later. Detected: (not found).

The runner's base image does not include a .NET SDK. The missing prerequisite was
installed only inside the isolated test volume:

curl -fsSL https://dot.net/v1/dotnet-install.sh \
  | bash -s -- --channel 10.0 --install-dir /workspace/.aspire/dotnet --no-path
export DOTNET_ROOT=/workspace/.aspire/dotnet
export PATH="$DOTNET_ROOT:$PATH"

Result: Installed SDK 10.0.401, runtime 10.0.12; subsequent starts succeeded.
This was an environment failure, not a DCP or PR failure. No bundle extraction or
layout repair was needed.

Fresh project creation

The following command was executed separately for NormalSmoke, BurstSmoke,
InvalidApi, InvalidAdditional, and InvalidCombined, substituting each name:

cli=/workspace/.aspire/dogfood/pr-20752/bin/aspire
"$cli" new aspire-empty \
  --name NormalSmoke \
  --output /workspace/NormalSmoke \
  --source /workspace/.aspire/hives/pr-20752/packages \
  --version 17.0.0-pr.20752.g065920e9 \
  --language csharp \
  --localhost-tld false \
  --suppress-agent-init \
  --non-interactive

Result: All five fresh C# file-based AppHosts were created successfully.
Generated SDK/bundle settings and NuGet configuration were preserved.

Test Scenarios Executed

Scenario 1: Normal DCP orchestration

Objective: Exercise actual DCP creation, process startup, dependency ordering,
log delivery, and cleanup with the PR Hosting assembly.

Coverage type: Happy path.

Status: Passed after installing the missing SDK prerequisite.

The AppHost declared three shell executable resources with a dependency chain
root -> middle -> leaf. Each emitted periodic stdout.

apphost=/workspace/NormalSmoke/apphost.cs
"$cli" start --apphost "$apphost" --launch-profile http --isolated --non-interactive --format Json
for name in root middle leaf; do
  "$cli" wait "$name" --status up --timeout 120 --apphost "$apphost" --non-interactive
done
"$cli" describe --apphost "$apphost" --format Json --include-hidden --non-interactive
"$cli" logs --apphost "$apphost" --tail 10 --non-interactive
"$cli" stop --apphost "$apphost" --non-interactive
"$cli" ps --format Json --non-interactive

Observations:

  • All three application resources reported Running and Healthy.
  • Structured resource output contained the exact intended WaitFor edges.
  • Dependency-wait messages and process stdout reached the CLI.
  • The running AppHost loaded Hosting version 17.0.0-pr.20752.g065920e9.
  • Stop succeeded, and the AppHost registry was [] afterward.

Evidence: pr20752-normal-retry.log, pr20752-invalid.log (loaded assembly
identity), and pr20752-evidence/normal/.

Scenario 2: Resource burst and established stream lifetime

Objective: Exercise concurrent real DCP process creation and confirm that a
short API budget does not cap established resource-watch or console-log streams.

Coverage type: Happy path and supported configuration boundary.

Status: Passed.

A fresh AppHost declared 40 shell processes and configured:

DcpPublisher:KubernetesApiTimeout = 00:00:05
DcpPublisher:KubernetesInitializationAdditionalTimeout = 00:00:00
DcpPublisher:KubernetesCreateRecoveryTimeout = 00:00:30

The test script started the AppHost, launched a native CLI readiness wait for
each of the 40 named workers, captured structured resource state, and opened
watch and log followers for worker-00. It then waited 12 seconds, verified both
followers were still active, restarted the worker, checked its new state and
logs, stopped the followers, and stopped the AppHost.

Key commands:

apphost=/workspace/BurstSmoke/apphost.cs
"$cli" start --apphost "$apphost" --launch-profile http --isolated --non-interactive --format Json
"$cli" wait worker-00 --status up --timeout 120 --apphost "$apphost" --non-interactive
# The same readiness command was run for every worker through worker-39.
"$cli" describe --apphost "$apphost" --format Json --non-interactive
"$cli" describe worker-00 --follow --format Json --apphost "$apphost" --non-interactive
"$cli" logs worker-00 --follow --format Json --apphost "$apphost" --non-interactive
# After 12 seconds:
"$cli" logs worker-00 --tail 30 --apphost "$apphost" --non-interactive
"$cli" resource worker-00 restart --apphost "$apphost" --non-interactive
"$cli" wait worker-00 --status up --timeout 120 --apphost "$apphost" --non-interactive
"$cli" stop --apphost "$apphost" --non-interactive
"$cli" ps --format Json --non-interactive

Observations:

  • Exactly 40 named workers were Running and Healthy, both before and after restart.
  • The five-second base budget and zero initialization allowance worked.
  • The same log follower received worker-00:tick:12, beyond the five-second API budget.
  • The watch follower received Running, Stopping, Finished, Starting,
    an intermediate empty state, and then Running after restart.
  • worker-00's actual process ID changed from 498 to 2397.
  • The same log follower received restarted-process output beginning at tick:0.
  • Both followers stopped cleanly, AppHost stop succeeded, and the registry was [].

Evidence: pr20752-burst.log, pr20752-evidence-verification.log, and
pr20752-evidence/burst/. The preserved pr20752-evidence/run-burst.sh contains
the full command sequence.

Scenario 3: Invalid timeout configuration

Objective: Verify the actual AppHost startup path rejects invalid timeout
settings with the correct options-validation error.

Coverage type: Unhappy path and bounds.

Status: Passed.

Three separate fresh AppHosts used the following invalid configurations:

AppHost Configuration Expected outcome
InvalidApi API timeout 00:00:00 API timeout must be between one second and ten minutes
InvalidAdditional Additional initialization timeout -00:00:01 Additional initialization timeout must be non-negative
InvalidCombined API timeout 00:10:00, additional initialization 00:00:01 Combined initialization budget must not exceed ten minutes

For each AppHost:

"$cli" start --apphost "/workspace/$name/apphost.cs" \
  --launch-profile http --isolated --non-interactive --format Json

Observations: Each CLI start returned nonzero (2), with an
OptionsValidationException naming the expected property and exact range error.
None was mistaken for successful startup. The AppHost registry was empty afterward.

Evidence: pr20752-invalid.log and pr20752-evidence/invalid/.

Scenario 4: HTTP-backed recovery and options regressions

Objective: Validate failure paths that cannot be deterministically forced in
the ordinary live-DCP smoke apps.

Coverage type: Happy path, unhappy path, cancellation, and timeout boundaries.

Status: Passed: 97 tests, zero failures, zero skips.

Executed from the source worktree at the exact PR head:

MSBUILDTERMINALLOGGER=false ./dotnet.sh test \
  --project tests/Aspire.Hosting.Tests/Aspire.Hosting.Tests.csproj \
  --no-launch-profile --no-restore /p:SkipNativeBuild=true \
  -- \
  --filter-class '*.KubernetesServiceTests' \
  --filter-class '*.ConfigureDefaultDcpOptionsTests' \
  --filter-not-trait 'quarantined=true' \
  --filter-not-trait 'outerloop=true'

The run compiled and passed in approximately 58 seconds. Coverage includes
complete HTTP 504 after commit, pre-header attempt timeouts with committed and
uncommitted outcomes, confirmation before retry, initial conflict/permanent
failures, Retry-After handling, setup failure versus attempted creation, caller
cancellation, total recovery deadlines, readiness changes, configuration ranges,
and established watch/log stream lifetime.

No partial-response-body stall scenarios were added or run.

Evidence: pr20752-regressions.log.

Evidence Verification

The structured JSON/NDJSON artifacts were checked independently of the CLI's
success messages. Assertions verified exact worker names/counts, healthy/running
states, exact dependency edges, the changed process ID, streamed restart
transitions, log output beyond the API deadline, post-restart logs, all three
specific validation errors, and empty AppHost registries after shutdown.

Result: Passed. See pr20752-evidence-verification.log.

Summary

Scenario Status Notes
Artifact identity Passed CLI and loaded Hosting assembly match PR head; CI merge parent verified
Normal orchestration Passed Three dependent application resources; clean shutdown
Burst and streams Passed 40 workers; streams survive five-second budget; restart observed
Invalid configuration Passed Three explicit startup validation failures
Focused regressions Passed 97 passed, zero failed/skipped

Overall Result

PR VERIFIED for the approved testing scope.

Limitations

  • This does not reproduce the original Intel macOS / Lima / QEMU software-emulation
    environment from issue #20691.
  • Real DCP smoke tests exercised normal and burst creation, watch/log delivery,
    restart, and cleanup. Ambiguous 504/timeout recovery was validated with the
    existing HTTP-backed service tests, not by forcing a real DCP server to stall.
  • The live stream check used a five-second API budget and observed the stream
    across a longer interval; it was not a multi-hour soak.
  • Dashboard resource state was verified through structured CLI output; no
    screenshots or visual UI assertions were needed for this hosting-only change.
  • No local automated E2E suite or additional full-suite run was performed.
  • No product code, PR description, commits, or pushes were changed by testing.

Report, Evidence, and Cleanup Status

  • Persistent report: files/pr20752-testing-report.md in this session.
  • Persistent logs: files/pr20752-*.log.
  • Persistent structured evidence: files/pr20752-evidence/.
  • PR comment: Posted with user approval.
  • Processes: All test-owned AppHosts and followers stopped. Ephemeral runner containers exited and were removed.
  • Temporary workspace: Removed with user approval after preserving evidence.
  • Owned Docker state volume: aspire-pr-state-5e244cde43fc, removed with user approval.

Preserve the DCP recovery tests while removing the filesystem warning suppression retired on main.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Tests selector

50 / 98 PR test projects · 4 PR jobs, from 5 changed files.

Selected PR test projects (50 / 98)

Aspire.Cli.EndToEnd.Tests, Aspire.Hosting.Analyzers.Tests, Aspire.Hosting.Azure.Kubernetes.Tests, Aspire.Hosting.Azure.Kusto.Tests, Aspire.Hosting.Azure.Provisioning.Tests, Aspire.Hosting.Azure.Tests, Aspire.Hosting.Blazor.Tests, Aspire.Hosting.Browsers.Tests, Aspire.Hosting.CodeGeneration.Go.Tests, Aspire.Hosting.CodeGeneration.Java.Tests, Aspire.Hosting.CodeGeneration.Python.Tests, Aspire.Hosting.CodeGeneration.Rust.Tests, Aspire.Hosting.CodeGeneration.TypeScript.Tests, Aspire.Hosting.Containers.Tests, Aspire.Hosting.DevTunnels.Tests, Aspire.Hosting.Docker.Tests, Aspire.Hosting.Dotnet.Tests, Aspire.Hosting.DotnetTool.Tests, Aspire.Hosting.EntityFrameworkCore.Tests, Aspire.Hosting.Foundry.Tests, Aspire.Hosting.Garnet.Tests, Aspire.Hosting.Go.Tests, Aspire.Hosting.Java.Tests, Aspire.Hosting.JavaScript.Tests, Aspire.Hosting.Kafka.Tests, Aspire.Hosting.Keycloak.Tests, Aspire.Hosting.Kubernetes.Tests, Aspire.Hosting.Maui.Tests, Aspire.Hosting.Milvus.Tests, Aspire.Hosting.MongoDB.Tests, Aspire.Hosting.MySql.Tests, Aspire.Hosting.Nats.Tests, Aspire.Hosting.OpenAI.Tests, Aspire.Hosting.Oracle.Tests, Aspire.Hosting.Orleans.Tests, Aspire.Hosting.PostgreSQL.Tests, Aspire.Hosting.Python.Tests, Aspire.Hosting.Qdrant.Tests, Aspire.Hosting.RabbitMQ.Tests, Aspire.Hosting.Radius.Tests, Aspire.Hosting.Redis.Tests, Aspire.Hosting.RemoteHost.Tests, Aspire.Hosting.Rust.Tests, Aspire.Hosting.Seq.Tests, Aspire.Hosting.SqlServer.Tests, Aspire.Hosting.Testing.Tests, Aspire.Hosting.Tests, Aspire.Hosting.Valkey.Tests, Aspire.Hosting.Yarp.Tests, Aspire.Playground.Tests

Selected PR jobs (4)

cli-starter-validation, extension-e2e, polyglot, typescript-api-compat


How these were chosen — grouped by what changed

⚠️ 45 of the 50 selected test projects come from a single change — src/Aspire.Hosting/Dcp/DcpKubernetesClient.cs.

🔧 src/Aspire.Hosting/Dcp/DcpKubernetesClient.cs (changed source)
→ 45 via the project graph

show 45

Aspire.Hosting.Analyzers.Tests (2 hops), Aspire.Hosting.Azure.Kubernetes.Tests (2 hops), Aspire.Hosting.Azure.Kusto.Tests (2 hops), Aspire.Hosting.Azure.Provisioning.Tests (3 hops), Aspire.Hosting.Azure.Tests, Aspire.Hosting.Browsers.Tests (2 hops), Aspire.Hosting.CodeGeneration.Go.Tests, Aspire.Hosting.CodeGeneration.Java.Tests, Aspire.Hosting.CodeGeneration.Python.Tests, Aspire.Hosting.CodeGeneration.Rust.Tests, Aspire.Hosting.CodeGeneration.TypeScript.Tests, Aspire.Hosting.Containers.Tests (2 hops), Aspire.Hosting.DevTunnels.Tests (2 hops), Aspire.Hosting.Docker.Tests (2 hops), Aspire.Hosting.DotnetTool.Tests (2 hops), Aspire.Hosting.EntityFrameworkCore.Tests (2 hops), Aspire.Hosting.Foundry.Tests (2 hops), Aspire.Hosting.Garnet.Tests (2 hops), Aspire.Hosting.Go.Tests (2 hops), Aspire.Hosting.Java.Tests (2 hops), Aspire.Hosting.JavaScript.Tests (2 hops), Aspire.Hosting.Kafka.Tests (2 hops), Aspire.Hosting.Keycloak.Tests (2 hops), Aspire.Hosting.Kubernetes.Tests (2 hops), Aspire.Hosting.Maui.Tests, Aspire.Hosting.Milvus.Tests (2 hops), Aspire.Hosting.MongoDB.Tests (2 hops), Aspire.Hosting.MySql.Tests (2 hops), Aspire.Hosting.Nats.Tests (2 hops), Aspire.Hosting.OpenAI.Tests (2 hops), Aspire.Hosting.Oracle.Tests (2 hops), Aspire.Hosting.Orleans.Tests (2 hops), Aspire.Hosting.PostgreSQL.Tests (2 hops), Aspire.Hosting.Python.Tests (2 hops), Aspire.Hosting.Qdrant.Tests (2 hops), Aspire.Hosting.RabbitMQ.Tests (2 hops), Aspire.Hosting.Redis.Tests (2 hops), Aspire.Hosting.RemoteHost.Tests, Aspire.Hosting.Rust.Tests (2 hops), Aspire.Hosting.Seq.Tests (2 hops), Aspire.Hosting.SqlServer.Tests (2 hops), Aspire.Hosting.Testing.Tests (2 hops), Aspire.Hosting.Valkey.Tests (2 hops), Aspire.Hosting.Yarp.Tests (2 hops), Aspire.Playground.Tests

🧪 tests/Aspire.Hosting.Tests/Dcp/ConfigureDefaultDcpOptionsTests.cs (changed test)
→ 1 directly: Aspire.Hosting.Tests
→ 3 via the project graph: Aspire.Hosting.Blazor.Tests, Aspire.Hosting.Dotnet.Tests, Aspire.Hosting.Radius.Tests

📦 affected project Aspire.Hosting
→ 1 test: Aspire.Cli.EndToEnd.Tests

🧪 tests/Aspire.Hosting.Tests/Dcp/KubernetesServiceTests.cs (changed test)
→ 1 directly: Aspire.Hosting.Tests

Job reasons

Job Triggered by
cli-starter-validation affected project Aspire.Hosting.PostgreSQL
extension-e2e • src/Aspire.Hosting/Dcp/DcpKubernetesClient.cs, src/Aspire.Hosting/Dcp/DcpOptions.cs, src/Aspire.Hosting/Dcp/KubernetesService.cs
• affected project Aspire.Hosting
polyglot • affected project Aspire.Hosting
• affected project Aspire.Hosting.Azure.Provisioning
typescript-api-compat affected project Aspire.Hosting

Selection computed for commit 1ad7cef.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The newly timeout-governed cleanup polling path lacks focused regression coverage.

1 open finding

🧠 Review effort: Balanced

@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
Contributor

Retrying the failed CI jobs for this pull request from the CI run attempt. The rerun is being tracked in the rerun attempt.

@danegsta David Negstad (danegsta) added area-orchestrator and removed needs-area-label An area label is needed to ensure this gets routed to the appropriate area owners labels Oct 9, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No high-confidence blocking issues found. Reviewed recovery design, cancellation and retry edge cases, configuration validation, and regression coverage. Validation at this head: 62/62 focused KubernetesServiceTests passed; controlled stalled-create recovery succeeded; live Windows DCP started a resource with custom timeout settings and shut down cleanly; invalid timeout configuration was rejected. The original macOS Intel HTTP 504 scenario was not reproduced exactly.

@danegsta
David Negstad (danegsta) merged commit ccc9d55 into main Oct 10, 2026
590 of 596 checks passed
@danegsta

Copy link
Copy Markdown
Member Author

/backport to release/13.6

@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 17.0 milestone Oct 10, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Started backporting to release/13.6 (link to workflow run)

aspire-repo-bot Bot added a commit to microsoft/aspire.dev that referenced this pull request Oct 10, 2026
Documents the new DcpPublisher:KubernetesApiTimeout,
KubernetesInitializationAdditionalTimeout, and
KubernetesCreateRecoveryTimeout options added in
microsoft/aspire#20752, along with the ambiguous-create
recovery behavior they enable.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Oct 30, 2026
github-actions Bot pushed a commit to MrD4rkne/oweme-ecosystem that referenced this pull request Oct 30, 2026
Updated [Aspire.Hosting.AppHost](https://github.com/microsoft/aspire)
from 13.6.3 to 13.6.4.

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

_Sourced from [Aspire.Hosting.AppHost's
releases](https://github.com/microsoft/aspire/releases)._

## 13.6.4

## What's New in Aspire 13.6.4

Patch release for Aspire 13.6 that improves resource startup
reliability, fixes Azure publishing with parameterized enum properties
in TypeScript AppHosts, and tightens CLI diagnostic log permissions on
Unix.

### 🐛 Fixes

- 🖥️ **Resources could fail to start after a DCP create request timed
out** — AppHost now checks whether a resource was created before
retrying a timed-out or HTTP 504 request, avoiding a premature
`FailedToStart` state when DCP completed the operation. API operations
default to a 40-second timeout with an additional 20-second allowance
before the first successful operation, and resource creation has a
two-minute recovery budget. These limits can be configured through
`DcpPublisher:KubernetesApiTimeout`,
`DcpPublisher:KubernetesInitializationAdditionalTimeout`, and
`DcpPublisher:KubernetesCreateRecoveryTimeout`. Established watch and
log streams are not limited by these operation timeouts. Addresses
startup timeouts reported in 13.6. Fixes
[#​20691](microsoft/aspire#20691).
([#​20868](microsoft/aspire#20868), backport of
[#​20752](microsoft/aspire#20752), @​danegsta)

- ☁️ **TypeScript AppHosts could fail to publish parameterized Azure
enum properties** — Assigning a `bicep().parameter(...)` expression to
an enum-valued provisioning property, such as an Azure Storage SKU name,
now works instead of failing with a type-assignment error. Type checking
for literal values and incompatible expression types is preserved. Fixes
a scenario introduced with the Azure provisioning proxy feature in 13.6.
([#​20767](microsoft/aspire#20767), backport of
[#​20557](microsoft/aspire#20557),
@​sebastienros)

- 🔒 **CLI diagnostic logs now use owner-only permissions on Unix** — Log
files are restricted to owner read/write access (`0600`), including
reused files, and the dedicated Aspire logs directory uses owner-only
access (`0700`), repairing existing permissions when needed. Newly
created custom log directories also use `0700`; existing custom parent
directories and Windows permission behavior are unchanged. Diagnostic
logs can contain sensitive data, including dashboard login URLs, so
review them before sharing.
([#​21282](microsoft/aspire#21282), backport of
[#​21276](microsoft/aspire#21276), @​mitchdenny)

---

*Full Changelog:
[v13.6.3...v13.6.4](microsoft/aspire@v13.6.3...v13.6.4)*

*Full commit:
[c89352703f78ae46de90fbf751ed8b52b77b89bf](microsoft/aspire@c89352703f78ae46de90fbf751ed8b52b77b89bf)*


Commits viewable in [compare
view](microsoft/aspire@v13.6.3...v13.6.4).
</details>

Updated [Aspire.Hosting.PostgreSQL](https://github.com/microsoft/aspire)
from 13.6.3 to 13.6.4.

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

_Sourced from [Aspire.Hosting.PostgreSQL's
releases](https://github.com/microsoft/aspire/releases)._

## 13.6.4

## What's New in Aspire 13.6.4

Patch release for Aspire 13.6 that improves resource startup
reliability, fixes Azure publishing with parameterized enum properties
in TypeScript AppHosts, and tightens CLI diagnostic log permissions on
Unix.

### 🐛 Fixes

- 🖥️ **Resources could fail to start after a DCP create request timed
out** — AppHost now checks whether a resource was created before
retrying a timed-out or HTTP 504 request, avoiding a premature
`FailedToStart` state when DCP completed the operation. API operations
default to a 40-second timeout with an additional 20-second allowance
before the first successful operation, and resource creation has a
two-minute recovery budget. These limits can be configured through
`DcpPublisher:KubernetesApiTimeout`,
`DcpPublisher:KubernetesInitializationAdditionalTimeout`, and
`DcpPublisher:KubernetesCreateRecoveryTimeout`. Established watch and
log streams are not limited by these operation timeouts. Addresses
startup timeouts reported in 13.6. Fixes
[#​20691](microsoft/aspire#20691).
([#​20868](microsoft/aspire#20868), backport of
[#​20752](microsoft/aspire#20752), @​danegsta)

- ☁️ **TypeScript AppHosts could fail to publish parameterized Azure
enum properties** — Assigning a `bicep().parameter(...)` expression to
an enum-valued provisioning property, such as an Azure Storage SKU name,
now works instead of failing with a type-assignment error. Type checking
for literal values and incompatible expression types is preserved. Fixes
a scenario introduced with the Azure provisioning proxy feature in 13.6.
([#​20767](microsoft/aspire#20767), backport of
[#​20557](microsoft/aspire#20557),
@​sebastienros)

- 🔒 **CLI diagnostic logs now use owner-only permissions on Unix** — Log
files are restricted to owner read/write access (`0600`), including
reused files, and the dedicated Aspire logs directory uses owner-only
access (`0700`), repairing existing permissions when needed. Newly
created custom log directories also use `0700`; existing custom parent
directories and Windows permission behavior are unchanged. Diagnostic
logs can contain sensitive data, including dashboard login URLs, so
review them before sharing.
([#​21282](microsoft/aspire#21282), backport of
[#​21276](microsoft/aspire#21276), @​mitchdenny)

---

*Full Changelog:
[v13.6.3...v13.6.4](microsoft/aspire@v13.6.3...v13.6.4)*

*Full commit:
[c89352703f78ae46de90fbf751ed8b52b77b89bf](microsoft/aspire@c89352703f78ae46de90fbf751ed8b52b77b89bf)*


Commits viewable in [compare
view](microsoft/aspire@v13.6.3...v13.6.4).
</details>

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

<!-- coderabbit-ai-generated:v1 -->

## Summary by CodeRabbit

* **Chores**
* Updated the versions of Aspire Hosting AppHost and PostgreSQL to
13.6.4.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
github-actions Bot pushed a commit to MrD4rkne/oweme-ecosystem that referenced this pull request Oct 30, 2026
Updated [Aspire.Hosting.AppHost](https://github.com/microsoft/aspire)
from 13.6.3 to 13.6.4.

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

_Sourced from [Aspire.Hosting.AppHost's
releases](https://github.com/microsoft/aspire/releases)._

## 13.6.4

## What's New in Aspire 13.6.4

Patch release for Aspire 13.6 that improves resource startup
reliability, fixes Azure publishing with parameterized enum properties
in TypeScript AppHosts, and tightens CLI diagnostic log permissions on
Unix.

### 🐛 Fixes

- 🖥️ **Resources could fail to start after a DCP create request timed
out** — AppHost now checks whether a resource was created before
retrying a timed-out or HTTP 504 request, avoiding a premature
`FailedToStart` state when DCP completed the operation. API operations
default to a 40-second timeout with an additional 20-second allowance
before the first successful operation, and resource creation has a
two-minute recovery budget. These limits can be configured through
`DcpPublisher:KubernetesApiTimeout`,
`DcpPublisher:KubernetesInitializationAdditionalTimeout`, and
`DcpPublisher:KubernetesCreateRecoveryTimeout`. Established watch and
log streams are not limited by these operation timeouts. Addresses
startup timeouts reported in 13.6. Fixes
[#​20691](https://github.com/microsoft/aspire/issues/20691).
([#​20868](https://github.com/microsoft/aspire/pull/20868), backport of
[#​20752](https://github.com/microsoft/aspire/pull/20752), @​danegsta)

- ☁️ **TypeScript AppHosts could fail to publish parameterized Azure
enum properties** — Assigning a `bicep().parameter(...)` expression to
an enum-valued provisioning property, such as an Azure Storage SKU name,
now works instead of failing with a type-assignment error. Type checking
for literal values and incompatible expression types is preserved. Fixes
a scenario introduced with the Azure provisioning proxy feature in 13.6.
([#​20767](https://github.com/microsoft/aspire/pull/20767), backport of
[#​20557](https://github.com/microsoft/aspire/pull/20557),
@​sebastienros)

- 🔒 **CLI diagnostic logs now use owner-only permissions on Unix** — Log
files are restricted to owner read/write access (`0600`), including
reused files, and the dedicated Aspire logs directory uses owner-only
access (`0700`), repairing existing permissions when needed. Newly
created custom log directories also use `0700`; existing custom parent
directories and Windows permission behavior are unchanged. Diagnostic
logs can contain sensitive data, including dashboard login URLs, so
review them before sharing.
([#​21282](https://github.com/microsoft/aspire/pull/21282), backport of
[#​21276](https://github.com/microsoft/aspire/pull/21276), @​mitchdenny)

---

*Full Changelog:
[v13.6.3...v13.6.4](https://github.com/microsoft/aspire/compare/v13.6.3...v13.6.4)*

*Full commit:
[c89352703f78ae46de90fbf751ed8b52b77b89bf](https://github.com/microsoft/aspire/commit/c89352703f78ae46de90fbf751ed8b52b77b89bf)*


Commits viewable in [compare
view](https://github.com/microsoft/aspire/compare/v13.6.3...v13.6.4).
</details>

Updated [Aspire.Hosting.PostgreSQL](https://github.com/microsoft/aspire)
from 13.6.3 to 13.6.4.

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

_Sourced from [Aspire.Hosting.PostgreSQL's
releases](https://github.com/microsoft/aspire/releases)._

## 13.6.4

## What's New in Aspire 13.6.4

Patch release for Aspire 13.6 that improves resource startup
reliability, fixes Azure publishing with parameterized enum properties
in TypeScript AppHosts, and tightens CLI diagnostic log permissions on
Unix.

### 🐛 Fixes

- 🖥️ **Resources could fail to start after a DCP create request timed
out** — AppHost now checks whether a resource was created before
retrying a timed-out or HTTP 504 request, avoiding a premature
`FailedToStart` state when DCP completed the operation. API operations
default to a 40-second timeout with an additional 20-second allowance
before the first successful operation, and resource creation has a
two-minute recovery budget. These limits can be configured through
`DcpPublisher:KubernetesApiTimeout`,
`DcpPublisher:KubernetesInitializationAdditionalTimeout`, and
`DcpPublisher:KubernetesCreateRecoveryTimeout`. Established watch and
log streams are not limited by these operation timeouts. Addresses
startup timeouts reported in 13.6. Fixes
[#​20691](https://github.com/microsoft/aspire/issues/20691).
([#​20868](https://github.com/microsoft/aspire/pull/20868), backport of
[#​20752](https://github.com/microsoft/aspire/pull/20752), @​danegsta)

- ☁️ **TypeScript AppHosts could fail to publish parameterized Azure
enum properties** — Assigning a `bicep().parameter(...)` expression to
an enum-valued provisioning property, such as an Azure Storage SKU name,
now works instead of failing with a type-assignment error. Type checking
for literal values and incompatible expression types is preserved. Fixes
a scenario introduced with the Azure provisioning proxy feature in 13.6.
([#​20767](https://github.com/microsoft/aspire/pull/20767), backport of
[#​20557](https://github.com/microsoft/aspire/pull/20557),
@​sebastienros)

- 🔒 **CLI diagnostic logs now use owner-only permissions on Unix** — Log
files are restricted to owner read/write access (`0600`), including
reused files, and the dedicated Aspire logs directory uses owner-only
access (`0700`), repairing existing permissions when needed. Newly
created custom log directories also use `0700`; existing custom parent
directories and Windows permission behavior are unchanged. Diagnostic
logs can contain sensitive data, including dashboard login URLs, so
review them before sharing.
([#​21282](https://github.com/microsoft/aspire/pull/21282), backport of
[#​21276](https://github.com/microsoft/aspire/pull/21276), @​mitchdenny)

---

*Full Changelog:
[v13.6.3...v13.6.4](https://github.com/microsoft/aspire/compare/v13.6.3...v13.6.4)*

*Full commit:
[c89352703f78ae46de90fbf751ed8b52b77b89bf](https://github.com/microsoft/aspire/commit/c89352703f78ae46de90fbf751ed8b52b77b89bf)*


Commits viewable in [compare
view](https://github.com/microsoft/aspire/compare/v13.6.3...v13.6.4).
</details>

Updated
[Microsoft.AspNetCore.Authentication.JwtBearer](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.AspNetCore.Authentication.JwtBearer's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.AspNetCore.Mvc.Testing](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.AspNetCore.Mvc.Testing's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated [Microsoft.AspNetCore.OpenApi](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.AspNetCore.OpenApi's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated [Microsoft.Bcl.TimeProvider](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.Bcl.TimeProvider's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.EntityFrameworkCore](https://github.com/dotnet/dotnet) from
10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.EntityFrameworkCore's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.EntityFrameworkCore.Abstractions](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.EntityFrameworkCore.Abstractions's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.EntityFrameworkCore.Design](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.EntityFrameworkCore.Design's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.EntityFrameworkCore.Tools](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.EntityFrameworkCore.Tools's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.Extensions.ApiDescription.Server](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.Extensions.ApiDescription.Server's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.Extensions.Caching.Memory](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.Extensions.Caching.Memory's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.Extensions.Configuration.EnvironmentVariables](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.Extensions.Configuration.EnvironmentVariables's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.Extensions.Configuration.Json](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.Extensions.Configuration.Json's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.Extensions.DependencyInjection.Abstractions](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.Extensions.DependencyInjection.Abstractions's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from
[Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.Extensions.Hosting.Abstractions](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.Extensions.Hosting.Abstractions's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated [Microsoft.Extensions.Http](https://github.com/dotnet/dotnet)
from 10.0.13 to 10.0.14.

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

_Sourced from [Microsoft.Extensions.Http's
releases](https://github.com/dotnet/dotnet/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/dotnet/dotnet/commits).
</details>

Updated
[Microsoft.Testing.Extensions.TrxReport](https://github.com/microsoft/testfx)
from 2.5.1 to 2.5.2.

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

_Sourced from [Microsoft.Testing.Extensions.TrxReport's
releases](https://github.com/microsoft/testfx/releases)._

No release notes found for this version range.

Commits viewable in [compare
view](https://github.com/microsoft/testfx/commits).
</details>

Updated [WolverineFx](http://github.com/jasperfx/wolverine) from 6.51.3
to 6.56.0.

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

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

## 6.56.0

## New

- **GH-5238** (#​5242): `opts.UseHttpTransport()` registers the HTTP
transport inside `UseWolverine()`. `http`/`https` URIs then resolve in
`ListenForMessagesFrom()`, `PublishMessage<T>().To(uri)`, and runtime
`EndpointFor()` / `ToDestination()`. Before this, the transport was only
registered by `ToHttpEndpoint()`, and any other `http` URI failed with
`Unknown Transport scheme 'http'`. `/_wolverine/invoke` now answers 415
instead of 500 for a content type with no registered serializer.

## Fixes

- **GH-5235** (#​5239): Host shutdown now stops the durability metrics
sweeper and waits for any query it has in flight before stores are
disposed. Removing a durability agent also waits for its in-flight
query. A metrics query could previously outlive `IHost.StopAsync()` and
throw `ObjectDisposedException` against a disposed `NpgsqlDataSource`.
- **GH-5236** (#​5240): A Kafka listener with a durable inbox no longer
crashes the process with a stack overflow when the inbox database is
unavailable. `DeferAsync()` used to call back into the receiver inline,
so the failed inbox write and the defer recursed. A deferred Kafka
envelope now goes back to the receiver on its own task after a short
pause, and only while the listener is running. After a stop or
inbox-recovery pause, its uncommitted offset brings it back. Because
Kafka has no native requeue, a `Requeue` error policy on a Kafka
endpoint now redelivers after about one second instead of immediately.
- **GH-5237** (#​5241): A CloudEvents HTTP endpoint now fails a
single-envelope send that the receiver rejects. It used to count the
send as delivered, so a durable endpoint aimed at `/_wolverine/invoke`
could delete an outgoing envelope that was never received. HTTP
transport responses are now disposed.


## 6.55.1

## Fixes

- **GH-5230** (#​5232): A database operation batch cancelled by
Wolverine's own shutdown is no longer wrapped in
`DatabaseBatchCommandException` and logged as an Error. Genuine
SQL/connection failures are still reported.
- **GH-5231** (#​5233): An `HttpEndpoint` aimed at `/_wolverine/invoke`
in its default (buffered) mode now delivers by posting each envelope
individually, instead of receiving a 415 for every batch and retrying
forever. `/batch/{queue}` and `.SendInline()` endpoints are unchanged.


## 6.55.0

## Highlights

**WolverineFx.Bobcat is out of alpha, on Bobcat 1.0.0** (#​5222,
#​5229). Bobcat 1.0.0 shipped tonight, and `WolverineFx.Bobcat` and
`WolverineFx.Bobcat.EventModel` now publish as stable **6.55.0** instead
of `-alpha.1`. `WolverineFx.Bobcat.Http` stays `6.55.0-alpha.1` until
Alba 9 ships stable, because a stable package cannot depend on Alba
9.0.0-rc.2. A spec project that `write-specs` generates with no
`--wolverine-version` pins the stable `WolverineFx.Bobcat` (#​5222,
#​5223).

**`MessageCausedBy` names your handler** (#​5224, #​5225).
`IWolverineObserver.MessageCausedBy` reported the generated handler
class
(`Internal.Generated.WolverineHandlers.StartTripHandler939323516`). It
now reports the handler you wrote (`TripService.StartTripHandler`), the
same string as the `message.handler` span tag, resolved at codegen time.
Code generated by an earlier version keeps working through the old
overload.

**CosmosDB sagas start with a conditional create** (#​5221, thanks
@​thechucklingatom). A second start message for an existing saga id used
to silently overwrite the running saga. It now fails with the
`SagaConcurrencyException` that Marten, Azure Blob and S3 already raise,
so one `OnException<SagaConcurrencyException>()` policy covers every
provider.

## Fixes
* GH-5217: `ListeningAgent.StartAsync` is serialized, and deliveries are
deferred to a drained `BufferedReceiver` (#​5228)
* GH-5218: an unresolvable tenant is treated as tenant-scoped on the
single-envelope inbox write (#​5227)
* GH-5220: Azure Service Bus listeners join their receive loop before
disposing the `CancellationTokenSource` (#​5226)
* GH-5215: reserved-word schema names are quoted in the remaining RDBMS
and PostgreSQL SQL (#​5216, thanks @​marc-RocketRez)
* GH-5213: a later pause supersedes an earlier pause's restart (#​5214)
* GH-5209: the dead letter history table round-trips with no schema
drift (#​5212)

## Dependencies
* JasperFx 2.96.0 (jasperfx#​1083: an Observed vs Derived `Origin` no
longer raises a `SourceDisagreement`)
* Weasel 9.47.0 (#​5219)
* Bobcat 1.0.0

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.54.0...V6.55.0


## 6.54.0

## Highlights

**Dead letter failure groups** (#​5209, #​5210). Wolverine now
fingerprints every message as it moves to dead letter storage, so dead
letters can be managed one failure group at a time:

* The default `IDeadLetterFingerprinter` hashes the exception type and
the first stack frame from application code. Register your own to
replace it.
* `DeadLetterEnvelopeQuery` gains `FailureGroup`,
`ExceptionMessageMatch` (Exact / Contains), `TenantId` and `Archived`.
* A new `SummarizeAllAsync` overload groups by failure group, message
type or endpoint, with first and last failure times.
* `ReplayMatchingAsync`, `DiscardMatchingAsync`, `ArchiveMatchingAsync`
and `RestoreMatchingAsync` report how many dead letters they affected.
* A message that fails again after a replay reports its `ReplayCount`,
`LastReplayedAt` and `FirstFailedAt`.
* Archived dead letters drop out of summaries, queries and replays until
restored, and can be expired separately with
`DurabilitySettings.ArchivedDeadLetterRetention`.
* `IDeadLetters.Capabilities` tells you what a store supports.

All changes are additive. The relational stores pick up seven nullable
columns on `wolverine_dead_letters`, an index and a new
`wolverine_dead_letter_history` table through the normal schema
migration. See the [dead letter storage
guide](https://wolverinefx.net/guide/durability/dead-letter-storage.html).

**Deduplication fixes** (#​5205, #​5206, #​5208), and **Bobcat
1.0.0-rc.4** dependency pins (#​5211). The `WolverineFx.Bobcat*`
packages remain alpha (`6.54.0-alpha.1`).


## What's Changed
* GH-5205, GH-5206: [DeduplicatedWithResponse] claim-in-transaction gaps
([WriteAggregate] T / [BoundaryModel], and repeats refused over
committed work) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5208
* Bobcat 1.0.0-rc.4 by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5211
* GH-5209 Dead letters: failure fingerprints, operation counts, replay
history, archive/restore and tenant scoping by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5210


**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.53.0...V6.54.0

## 6.53.0

## What's Changed
* GH-5202: keep the ASB response queue identity stable during startup by
@​DeandreT in https://github.com/JasperFx/wolverine/pull/5203

## New Contributors
* @​DeandreT made their first contribution in
https://github.com/JasperFx/wolverine/pull/5203

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.52.0...V6.53.0

## 6.52.0

Wolverine 6.52.0 is a feature release. The headline items are
Aspire-style registration by connection-string name for every transport
and every message store, timer agents for short-cadence recurring
schedules, and the 6.x groundwork for Wolverine 7.0's
one-chain-per-handler model. There are no breaking API changes. Two
behavior changes are worth knowing about up front: recurring schedules
that fire more often than every 15 minutes now run on a timer agent (opt
out per schedule with `UseScheduledMessages()`), and outgoing envelopes
a transport cannot map are dead-lettered instead of being logged and
deleted.

Many thanks to everyone who reported issues and sent fixes: @​uniquelau,
@​johnkaram02, @​erdtsieck, @​ahmetvayhan and @​pritamrao.

## Aspire parity: named connections

* Named-connection overloads for every transport (Aspire parity,
GH-5126) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5159
* Message storage by connection-string name for every RDBMS provider
(PostgreSQL, SQL Server, MySQL, SQLite, Oracle), `NpgsqlDataSource` /
`MySqlDataSource` from the container, named static tenants, a Named
Connection Strings table in `describe`, and docs that lead with the
named form (GH-5127, GH-5156) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5174
* Aspire samples moved to Aspire 13.6.3, added to `wolverine.slnx`, with
a ServiceDefaults project for traces, metrics and `/health` (GH-5124) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5182

## Messaging and error handling

* Timer agents for short-cadence recurring schedules: one agent per
schedule under `opts.Schedules.TimerThreshold` (15 minutes), same dedup
id as the scheduled path, pause and resume through
`IRecurringScheduleControl` (GH-5168) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5183
* `DoThenRetry(action, maxAttempts)` error policy that works both inline
and from a queue (GH-5068) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5179
* Unmappable outgoing envelopes are dead-lettered on Azure Service Bus,
SNS and Kafka instead of being reported as sent (GH-5055) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5185
* Durable outbox coalesces stores and deletes per tenant database, so
one slow tenant no longer holds back every tenant's sends (GH-5171) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5180
* 6.x prep for HandlerChain 1:1 in 7.0:
`MultipleHandlerBehavior.ClassicCombineIntoOneLogicalHandler` is
`[Obsolete]` (still the default), a startup warning for combined
handlers, opt-in `AssertNoCombinedHandlers()`, fixes for latent
`Separated` bugs, a `handler.type` OpenTelemetry tag on every chain, and
logical deduplication scoped per chain (GH-5133) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5184

## HTTP

* `[DeduplicatedWithResponse]` `ClaimInTransaction`, plus two Marten
commit-failure fixes (GH-5160, GH-5165, GH-5166) by @​jeremydmiller with
@​uniquelau in https://github.com/JasperFx/wolverine/pull/5169
* `WolverineHttpOptions.DefaultClaimInTransaction`, an application-wide
default (GH-5160) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5173
* A string response declares its UTF-8 byte count as `Content-Length`
(GH-5187) by @​johnkaram02 in
https://github.com/JasperFx/wolverine/pull/5188
* Bind array and list query parameters whose `[FromQuery]` name is not a
C# identifier (GH-5189) by @​johnkaram02 in
https://github.com/JasperFx/wolverine/pull/5190

## Operability and diagnostics

* `ServiceCapabilities` reads each store on its own and reports
`FailedSections`, so a failed section is distinguishable from an empty
one (GH-5162) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5175
* `AssignmentGrid.Agent.UnplacedReason` (`AwaitingCapacity`,
`NoCapableNode`, `Paused`, `TakeoverHold`, `Superseded`), a capacity log
line and an optional `NodeAcceptThreshold` (GH-5163) by @​jeremydmiller
in https://github.com/JasperFx/wolverine/pull/5176 and
https://github.com/JasperFx/wolverine/pull/5186
* Header-equality filter on `DeadLetterEnvelopeQuery`, honored by bulk
replay and discard, across every dead letter store (GH-5164) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5181
* `db-list` / `db-dump` / `db-patch` discover the Oracle message store
(GH-5172) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5177

## Documentation

* The remaining serverless and Cosmos DB documentation (GH-5054) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5178
* Memory sizing for managed event subscription distribution at tenants x
projections scale: set `MaximumHopperSize` to about 2 x `BatchSize`
(GH-5170, follow-up JasperFx/jasperfx#​1076) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5199

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.51.3...V6.52.0


Commits viewable in [compare
view](http://github.com/jasperfx/wolverine/compare/V6.51.3...V6.56.0).
</details>

Updated
[WolverineFx.FluentValidation](http://github.com/jasperfx/wolverine)
from 6.51.3 to 6.56.0.

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

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

## 6.56.0

## New

- **GH-5238** (#​5242): `opts.UseHttpTransport()` registers the HTTP
transport inside `UseWolverine()`. `http`/`https` URIs then resolve in
`ListenForMessagesFrom()`, `PublishMessage<T>().To(uri)`, and runtime
`EndpointFor()` / `ToDestination()`. Before this, the transport was only
registered by `ToHttpEndpoint()`, and any other `http` URI failed with
`Unknown Transport scheme 'http'`. `/_wolverine/invoke` now answers 415
instead of 500 for a content type with no registered serializer.

## Fixes

- **GH-5235** (#​5239): Host shutdown now stops the durability metrics
sweeper and waits for any query it has in flight before stores are
disposed. Removing a durability agent also waits for its in-flight
query. A metrics query could previously outlive `IHost.StopAsync()` and
throw `ObjectDisposedException` against a disposed `NpgsqlDataSource`.
- **GH-5236** (#​5240): A Kafka listener with a durable inbox no longer
crashes the process with a stack overflow when the inbox database is
unavailable. `DeferAsync()` used to call back into the receiver inline,
so the failed inbox write and the defer recursed. A deferred Kafka
envelope now goes back to the receiver on its own task after a short
pause, and only while the listener is running. After a stop or
inbox-recovery pause, its uncommitted offset brings it back. Because
Kafka has no native requeue, a `Requeue` error policy on a Kafka
endpoint now redelivers after about one second instead of immediately.
- **GH-5237** (#​5241): A CloudEvents HTTP endpoint now fails a
single-envelope send that the receiver rejects. It used to count the
send as delivered, so a durable endpoint aimed at `/_wolverine/invoke`
could delete an outgoing envelope that was never received. HTTP
transport responses are now disposed.


## 6.55.1

## Fixes

- **GH-5230** (#​5232): A database operation batch cancelled by
Wolverine's own shutdown is no longer wrapped in
`DatabaseBatchCommandException` and logged as an Error. Genuine
SQL/connection failures are still reported.
- **GH-5231** (#​5233): An `HttpEndpoint` aimed at `/_wolverine/invoke`
in its default (buffered) mode now delivers by posting each envelope
individually, instead of receiving a 415 for every batch and retrying
forever. `/batch/{queue}` and `.SendInline()` endpoints are unchanged.


## 6.55.0

## Highlights

**WolverineFx.Bobcat is out of alpha, on Bobcat 1.0.0** (#​5222,
#​5229). Bobcat 1.0.0 shipped tonight, and `WolverineFx.Bobcat` and
`WolverineFx.Bobcat.EventModel` now publish as stable **6.55.0** instead
of `-alpha.1`. `WolverineFx.Bobcat.Http` stays `6.55.0-alpha.1` until
Alba 9 ships stable, because a stable package cannot depend on Alba
9.0.0-rc.2. A spec project that `write-specs` generates with no
`--wolverine-version` pins the stable `WolverineFx.Bobcat` (#​5222,
#​5223).

**`MessageCausedBy` names your handler** (#​5224, #​5225).
`IWolverineObserver.MessageCausedBy` reported the generated handler
class
(`Internal.Generated.WolverineHandlers.StartTripHandler939323516`). It
now reports the handler you wrote (`TripService.StartTripHandler`), the
same string as the `message.handler` span tag, resolved at codegen time.
Code generated by an earlier version keeps working through the old
overload.

**CosmosDB sagas start with a conditional create** (#​5221, thanks
@​thechucklingatom). A second start message for an existing saga id used
to silently overwrite the running saga. It now fails with the
`SagaConcurrencyException` that Marten, Azure Blob and S3 already raise,
so one `OnException<SagaConcurrencyException>()` policy covers every
provider.

## Fixes
* GH-5217: `ListeningAgent.StartAsync` is serialized, and deliveries are
deferred to a drained `BufferedReceiver` (#​5228)
* GH-5218: an unresolvable tenant is treated as tenant-scoped on the
single-envelope inbox write (#​5227)
* GH-5220: Azure Service Bus listeners join their receive loop before
disposing the `CancellationTokenSource` (#​5226)
* GH-5215: reserved-word schema names are quoted in the remaining RDBMS
and PostgreSQL SQL (#​5216, thanks @​marc-RocketRez)
* GH-5213: a later pause supersedes an earlier pause's restart (#​5214)
* GH-5209: the dead letter history table round-trips with no schema
drift (#​5212)

## Dependencies
* JasperFx 2.96.0 (jasperfx#​1083: an Observed vs Derived `Origin` no
longer raises a `SourceDisagreement`)
* Weasel 9.47.0 (#​5219)
* Bobcat 1.0.0

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.54.0...V6.55.0


## 6.54.0

## Highlights

**Dead letter failure groups** (#​5209, #​5210). Wolverine now
fingerprints every message as it moves to dead letter storage, so dead
letters can be managed one failure group at a time:

* The default `IDeadLetterFingerprinter` hashes the exception type and
the first stack frame from application code. Register your own to
replace it.
* `DeadLetterEnvelopeQuery` gains `FailureGroup`,
`ExceptionMessageMatch` (Exact / Contains), `TenantId` and `Archived`.
* A new `SummarizeAllAsync` overload groups by failure group, message
type or endpoint, with first and last failure times.
* `ReplayMatchingAsync`, `DiscardMatchingAsync`, `ArchiveMatchingAsync`
and `RestoreMatchingAsync` report how many dead letters they affected.
* A message that fails again after a replay reports its `ReplayCount`,
`LastReplayedAt` and `FirstFailedAt`.
* Archived dead letters drop out of summaries, queries and replays until
restored, and can be expired separately with
`DurabilitySettings.ArchivedDeadLetterRetention`.
* `IDeadLetters.Capabilities` tells you what a store supports.

All changes are additive. The relational stores pick up seven nullable
columns on `wolverine_dead_letters`, an index and a new
`wolverine_dead_letter_history` table through the normal schema
migration. See the [dead letter storage
guide](https://wolverinefx.net/guide/durability/dead-letter-storage.html).

**Deduplication fixes** (#​5205, #​5206, #​5208), and **Bobcat
1.0.0-rc.4** dependency pins (#​5211). The `WolverineFx.Bobcat*`
packages remain alpha (`6.54.0-alpha.1`).


## What's Changed
* GH-5205, GH-5206: [DeduplicatedWithResponse] claim-in-transaction gaps
([WriteAggregate] T / [BoundaryModel], and repeats refused over
committed work) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5208
* Bobcat 1.0.0-rc.4 by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5211
* GH-5209 Dead letters: failure fingerprints, operation counts, replay
history, archive/restore and tenant scoping by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5210


**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.53.0...V6.54.0

## 6.53.0

## What's Changed
* GH-5202: keep the ASB response queue identity stable during startup by
@​DeandreT in https://github.com/JasperFx/wolverine/pull/5203

## New Contributors
* @​DeandreT made their first contribution in
https://github.com/JasperFx/wolverine/pull/5203

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.52.0...V6.53.0

## 6.52.0

Wolverine 6.52.0 is a feature release. The headline items are
Aspire-style registration by connection-string name for every transport
and every message store, timer agents for short-cadence recurring
schedules, and the 6.x groundwork for Wolverine 7.0's
one-chain-per-handler model. There are no breaking API changes. Two
behavior changes are worth knowing about up front: recurring schedules
that fire more often than every 15 minutes now run on a timer agent (opt
out per schedule with `UseScheduledMessages()`), and outgoing envelopes
a transport cannot map are dead-lettered instead of being logged and
deleted.

Many thanks to everyone who reported issues and sent fixes: @​uniquelau,
@​johnkaram02, @​erdtsieck, @​ahmetvayhan and @​pritamrao.

## Aspire parity: named connections

* Named-connection overloads for every transport (Aspire parity,
GH-5126) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5159
* Message storage by connection-string name for every RDBMS provider
(PostgreSQL, SQL Server, MySQL, SQLite, Oracle), `NpgsqlDataSource` /
`MySqlDataSource` from the container, named static tenants, a Named
Connection Strings table in `describe`, and docs that lead with the
named form (GH-5127, GH-5156) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5174
* Aspire samples moved to Aspire 13.6.3, added to `wolverine.slnx`, with
a ServiceDefaults project for traces, metrics and `/health` (GH-5124) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5182

## Messaging and error handling

* Timer agents for short-cadence recurring schedules: one agent per
schedule under `opts.Schedules.TimerThreshold` (15 minutes), same dedup
id as the scheduled path, pause and resume through
`IRecurringScheduleControl` (GH-5168) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5183
* `DoThenRetry(action, maxAttempts)` error policy that works both inline
and from a queue (GH-5068) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5179
* Unmappable outgoing envelopes are dead-lettered on Azure Service Bus,
SNS and Kafka instead of being reported as sent (GH-5055) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5185
* Durable outbox coalesces stores and deletes per tenant database, so
one slow tenant no longer holds back every tenant's sends (GH-5171) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5180
* 6.x prep for HandlerChain 1:1 in 7.0:
`MultipleHandlerBehavior.ClassicCombineIntoOneLogicalHandler` is
`[Obsolete]` (still the default), a startup warning for combined
handlers, opt-in `AssertNoCombinedHandlers()`, fixes for latent
`Separated` bugs, a `handler.type` OpenTelemetry tag on every chain, and
logical deduplication scoped per chain (GH-5133) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5184

## HTTP

* `[DeduplicatedWithResponse]` `ClaimInTransaction`, plus two Marten
commit-failure fixes (GH-5160, GH-5165, GH-5166) by @​jeremydmiller with
@​uniquelau in https://github.com/JasperFx/wolverine/pull/5169
* `WolverineHttpOptions.DefaultClaimInTransaction`, an application-wide
default (GH-5160) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5173
* A string response declares its UTF-8 byte count as `Content-Length`
(GH-5187) by @​johnkaram02 in
https://github.com/JasperFx/wolverine/pull/5188
* Bind array and list query parameters whose `[FromQuery]` name is not a
C# identifier (GH-5189) by @​johnkaram02 in
https://github.com/JasperFx/wolverine/pull/5190

## Operability and diagnostics

* `ServiceCapabilities` reads each store on its own and reports
`FailedSections`, so a failed section is distinguishable from an empty
one (GH-5162) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5175
* `AssignmentGrid.Agent.UnplacedReason` (`AwaitingCapacity`,
`NoCapableNode`, `Paused`, `TakeoverHold`, `Superseded`), a capacity log
line and an optional `NodeAcceptThreshold` (GH-5163) by @​jeremydmiller
in https://github.com/JasperFx/wolverine/pull/5176 and
https://github.com/JasperFx/wolverine/pull/5186
* Header-equality filter on `DeadLetterEnvelopeQuery`, honored by bulk
replay and discard, across every dead letter store (GH-5164) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5181
* `db-list` / `db-dump` / `db-patch` discover the Oracle message store
(GH-5172) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5177

## Documentation

* The remaining serverless and Cosmos DB documentation (GH-5054) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5178
* Memory sizing for managed event subscription distribution at tenants x
projections scale: set `MaximumHopperSize` to about 2 x `BatchSize`
(GH-5170, follow-up JasperFx/jasperfx#​1076) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5199

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.51.3...V6.52.0


Commits viewable in [compare
view](http://github.com/jasperfx/wolverine/compare/V6.51.3...V6.56.0).
</details>

Updated
[WolverineFx.RuntimeCompilation](http://github.com/jasperfx/wolverine)
from 6.51.3 to 6.56.0.

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

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

## 6.56.0

## New

- **GH-5238** (#​5242): `opts.UseHttpTransport()` registers the HTTP
transport inside `UseWolverine()`. `http`/`https` URIs then resolve in
`ListenForMessagesFrom()`, `PublishMessage<T>().To(uri)`, and runtime
`EndpointFor()` / `ToDestination()`. Before this, the transport was only
registered by `ToHttpEndpoint()`, and any other `http` URI failed with
`Unknown Transport scheme 'http'`. `/_wolverine/invoke` now answers 415
instead of 500 for a content type with no registered serializer.

## Fixes

- **GH-5235** (#​5239): Host shutdown now stops the durability metrics
sweeper and waits for any query it has in flight before stores are
disposed. Removing a durability agent also waits for its in-flight
query. A metrics query could previously outlive `IHost.StopAsync()` and
throw `ObjectDisposedException` against a disposed `NpgsqlDataSource`.
- **GH-5236** (#​5240): A Kafka listener with a durable inbox no longer
crashes the process with a stack overflow when the inbox database is
unavailable. `DeferAsync()` used to call back into the receiver inline,
so the failed inbox write and the defer recursed. A deferred Kafka
envelope now goes back to the receiver on its own task after a short
pause, and only while the listener is running. After a stop or
inbox-recovery pause, its uncommitted offset brings it back. Because
Kafka has no native requeue, a `Requeue` error policy on a Kafka
endpoint now redelivers after about one second instead of immediately.
- **GH-5237** (#​5241): A CloudEvents HTTP endpoint now fails a
single-envelope send that the receiver rejects. It used to count the
send as delivered, so a durable endpoint aimed at `/_wolverine/invoke`
could delete an outgoing envelope that was never received. HTTP
transport responses are now disposed.


## 6.55.1

## Fixes

- **GH-5230** (#​5232): A database operation batch cancelled by
Wolverine's own shutdown is no longer wrapped in
`DatabaseBatchCommandException` and logged as an Error. Genuine
SQL/connection failures are still reported.
- **GH-5231** (#​5233): An `HttpEndpoint` aimed at `/_wolverine/invoke`
in its default (buffered) mode now delivers by posting each envelope
individually, instead of receiving a 415 for every batch and retrying
forever. `/batch/{queue}` and `.SendInline()` endpoints are unchanged.


## 6.55.0

## Highlights

**WolverineFx.Bobcat is out of alpha, on Bobcat 1.0.0** (#​5222,
#​5229). Bobcat 1.0.0 shipped tonight, and `WolverineFx.Bobcat` and
`WolverineFx.Bobcat.EventModel` now publish as stable **6.55.0** instead
of `-alpha.1`. `WolverineFx.Bobcat.Http` stays `6.55.0-alpha.1` until
Alba 9 ships stable, because a stable package cannot depend on Alba
9.0.0-rc.2. A spec project that `write-specs` generates with no
`--wolverine-version` pins the stable `WolverineFx.Bobcat` (#​5222,
#​5223).

**`MessageCausedBy` names your handler** (#​5224, #​5225).
`IWolverineObserver.MessageCausedBy` reported the generated handler
class
(`Internal.Generated.WolverineHandlers.StartTripHandler939323516`). It
now reports the handler you wrote (`TripService.StartTripHandler`), the
same string as the `message.handler` span tag, resolved at codegen time.
Code generated by an earlier version keeps working through the old
overload.

**CosmosDB sagas start with a conditional create** (#​5221, thanks
@​thechucklingatom). A second start message for an existing saga id used
to silently overwrite the running saga. It now fails with the
`SagaConcurrencyException` that Marten, Azure Blob and S3 already raise,
so one `OnException<SagaConcurrencyException>()` policy covers every
provider.

## Fixes
* GH-5217: `ListeningAgent.StartAsync` is serialized, and deliveries are
deferred to a drained `BufferedReceiver` (#​5228)
* GH-5218: an unresolvable tenant is treated as tenant-scoped on the
single-envelope inbox write (#​5227)
* GH-5220: Azure Service Bus listeners join their receive loop before
disposing the `CancellationTokenSource` (#​5226)
* GH-5215: reserved-word schema names are quoted in the remaining RDBMS
and PostgreSQL SQL (#​5216, thanks @​marc-RocketRez)
* GH-5213: a later pause supersedes an earlier pause's restart (#​5214)
* GH-5209: the dead letter history table round-trips with no schema
drift (#​5212)

## Dependencies
* JasperFx 2.96.0 (jasperfx#​1083: an Observed vs Derived `Origin` no
longer raises a `SourceDisagreement`)
* Weasel 9.47.0 (#​5219)
* Bobcat 1.0.0

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.54.0...V6.55.0


## 6.54.0

## Highlights

**Dead letter failure groups** (#​5209, #​5210). Wolverine now
fingerprints every message as it moves to dead letter storage, so dead
letters can be managed one failure group at a time:

* The default `IDeadLetterFingerprinter` hashes the exception type and
the first stack frame from application code. Register your own to
replace it.
* `DeadLetterEnvelopeQuery` gains `FailureGroup`,
`ExceptionMessageMatch` (Exact / Contains), `TenantId` and `Archived`.
* A new `SummarizeAllAsync` overload groups by failure group, message
type or endpoint, with first and last failure times.
* `ReplayMatchingAsync`, `DiscardMatchingAsync`, `ArchiveMatchingAsync`
and `RestoreMatchingAsync` report how many dead letters they affected.
* A message that fails again after a replay reports its `ReplayCount`,
`LastReplayedAt` and `FirstFailedAt`.
* Archived dead letters drop out of summaries, queries and replays until
restored, and can be expired separately with
`DurabilitySettings.ArchivedDeadLetterRetention`.
* `IDeadLetters.Capabilities` tells you what a store supports.

All changes are additive. The relational stores pick up seven nullable
columns on `wolverine_dead_letters`, an index and a new
`wolverine_dead_letter_history` table through the normal schema
migration. See the [dead letter storage
guide](https://wolverinefx.net/guide/durability/dead-letter-storage.html).

**Deduplication fixes** (#​5205, #​5206, #​5208), and **Bobcat
1.0.0-rc.4** dependency pins (#​5211). The `WolverineFx.Bobcat*`
packages remain alpha (`6.54.0-alpha.1`).


## What's Changed
* GH-5205, GH-5206: [DeduplicatedWithResponse] claim-in-transaction gaps
([WriteAggregate] T / [BoundaryModel], and repeats refused over
committed work) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5208
* Bobcat 1.0.0-rc.4 by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5211
* GH-5209 Dead letters: failure fingerprints, operation counts, replay
history, archive/restore and tenant scoping by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5210


**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.53.0...V6.54.0

## 6.53.0

## What's Changed
* GH-5202: keep the ASB response queue identity stable during startup by
@​DeandreT in https://github.com/JasperFx/wolverine/pull/5203

## New Contributors
* @​DeandreT made their first contribution in
https://github.com/JasperFx/wolverine/pull/5203

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.52.0...V6.53.0

## 6.52.0

Wolverine 6.52.0 is a feature release. The headline items are
Aspire-style registration by connection-string name for every transport
and every message store, timer agents for short-cadence recurring
schedules, and the 6.x groundwork for Wolverine 7.0's
one-chain-per-handler model. There are no breaking API changes. Two
behavior changes are worth knowing about up front: recurring schedules
that fire more often than every 15 minutes now run on a timer agent (opt
out per schedule with `UseScheduledMessages()`), and outgoing envelopes
a transport cannot map are dead-lettered instead of being logged and
deleted.

Many thanks to everyone who reported issues and sent fixes: @​uniquelau,
@​johnkaram02, @​erdtsieck, @​ahmetvayhan and @​pritamrao.

## Aspire parity: named connections

* Named-connection overloads for every transport (Aspire parity,
GH-5126) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5159
* Message storage by connection-string name for every RDBMS provider
(PostgreSQL, SQL Server, MySQL, SQLite, Oracle), `NpgsqlDataSource` /
`MySqlDataSource` from the container, named static tenants, a Named
Connection Strings table in `describe`, and docs that lead with the
named form (GH-5127, GH-5156) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5174
* Aspire samples moved to Aspire 13.6.3, added to `wolverine.slnx`, with
a ServiceDefaults project for traces, metrics and `/health` (GH-5124) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5182

## Messaging and error handling

* Timer agents for short-cadence recurring schedules: one agent per
schedule under `opts.Schedules.TimerThreshold` (15 minutes), same dedup
id as the scheduled path, pause and resume through
`IRecurringScheduleControl` (GH-5168) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5183
* `DoThenRetry(action, maxAttempts)` error policy that works both inline
and from a queue (GH-5068) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5179
* Unmappable outgoing envelopes are dead-lettered on Azure Service Bus,
SNS and Kafka instead of being reported as sent (GH-5055) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5185
* Durable outbox coalesces stores and deletes per tenant database, so
one slow tenant no longer holds back every tenant's sends (GH-5171) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5180
* 6.x prep for HandlerChain 1:1 in 7.0:
`MultipleHandlerBehavior.ClassicCombineIntoOneLogicalHandler` is
`[Obsolete]` (still the default), a startup warning for combined
handlers, opt-in `AssertNoCombinedHandlers()`, fixes for latent
`Separated` bugs, a `handler.type` OpenTelemetry tag on every chain, and
logical deduplication scoped per chain (GH-5133) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5184

## HTTP

* `[DeduplicatedWithResponse]` `ClaimInTransaction`, plus two Marten
commit-failure fixes (GH-5160, GH-5165, GH-5166) by @​jeremydmiller with
@​uniquelau in https://github.com/JasperFx/wolverine/pull/5169
* `WolverineHttpOptions.DefaultClaimInTransaction`, an application-wide
default (GH-5160) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5173
* A string response declares its UTF-8 byte count as `Content-Length`
(GH-5187) by @​johnkaram02 in
https://github.com/JasperFx/wolverine/pull/5188
* Bind array and list query parameters whose `[FromQuery]` name is not a
C# identifier (GH-5189) by @​johnkaram02 in
https://github.com/JasperFx/wolverine/pull/5190

## Operability and diagnostics

* `ServiceCapabilities` reads each store on its own and reports
`FailedSections`, so a failed section is distinguishable from an empty
one (GH-5162) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5175
* `AssignmentGrid.Agent.UnplacedReason` (`AwaitingCapacity`,
`NoCapableNode`, `Paused`, `TakeoverHold`, `Superseded`), a capacity log
line and an optional `NodeAcceptThreshold` (GH-5163) by @​jeremydmiller
in https://github.com/JasperFx/wolverine/pull/5176 and
https://github.com/JasperFx/wolverine/pull/5186
* Header-equality filter on `DeadLetterEnvelopeQuery`, honored by bulk
replay and discard, across every dead letter store (GH-5164) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5181
* `db-list` / `db-dump` / `db-patch` discover the Oracle message store
(GH-5172) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5177

## Documentation

* The remaining serverless and Cosmos DB documentation (GH-5054) by
@​jeremydmiller in https://github.com/JasperFx/wolverine/pull/5178
* Memory sizing for managed event subscription distribution at tenants x
projections scale: set `MaximumHopperSize` to about 2 x `BatchSize`
(GH-5170, follow-up JasperFx/jasperfx#​1076) by @​jeremydmiller in
https://github.com/JasperFx/wolverine/pull/5199

**Full Changelog**:
https://github.com/JasperFx/wolverine/compare/V6.51.3...V6.52.0


Commits viewable in [compare
view](http://github.com/jasperfx/wolverine/compare/V6.51.3...V6.56.0).
</details>

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

<!-- coderabbit-ai-generated:v1 -->

## Summary by CodeRabbit

* **Chores**
* Updated versions of platform and application components, along with
testing tools. Other package settings remain unchanged. These updates do
not add or remove user-facing features.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A single timed-out or 504 DCP Create call permanently fails the resource (FailedToStart); not retried since 13.6.0

3 participants