Skip to content

chore(deps): clear all five package advisories, .NET 10 servicing patches, and test-tooling majors - #53

Merged
ChrisonSimtian merged 2 commits into
mainfrom
chore/dependency-security-bumps
Jul 26, 2026
Merged

chore(deps): clear all five package advisories, .NET 10 servicing patches, and test-tooling majors#53
ChrisonSimtian merged 2 commits into
mainfrom
chore/dependency-security-bumps

Conversation

@ChrisonSimtian

@ChrisonSimtian ChrisonSimtian commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

A dotnet list package --vulnerable --include-transitive sweep found five advisories, not the one that happened to surface as a build warning — the rest were being lost in NU19xx noise. All are now clear.

Security

Package Advisory Note
OpenTelemetry.* 1.11.x → 1.17.0 GHSA-g94r-2vxg-569j, GHSA-4625-4j76-fww9 Highest real impactServiceDefaults is referenced by every host, so this shipped everywhere. Prometheus exporter 1.10.0-beta.11.17.0-beta.1 to stay in step.
SharpCompress 0.38.0 → 0.50.1 GHSA-6c8g-7p36-r338 Interim — its only consumer is the dead MediathekView parser that #49 deletes outright.
Aspire.Hosting* 13.1.2 → 13.4.6 GHSA-hv8m-jj95-wg3x Drops the StreamJsonRpc that carried MessagePack 2.5.192.
Fallout.Common/Components 10.3.49 → 10.4.0-rc.4 System.Security.Cryptography.Xml Picks up Microsoft.Build 18.0.2. Clears every advisory on the Nuke build project.

Servicing patches (same major, no API change)

  • EF Core + Design + SqlServer 10.0.410.0.10
  • Microsoft.Extensions.{Hosting.Abstractions,Configuration.Binder,Http} + Microsoft.AspNetCore.OpenApi 10.0.010.0.10
  • Riok.Mapperly 4.1.14.3.1

The Aspire bump needed a second, non-obvious change

Bumping the Aspire.Hosting* packages alone broke the fleet outright:

Aspire.Hosting.DistributedApplicationException: Newer version of the
Aspire.Hosting.AppHost package is required to run the application.
Ensure you are referencing at least version '13.4.6'.

<Sdk Name="Aspire.AppHost.Sdk" Version="13.1.2" /> in Krautwatch.AppHost.csproj separately pins Aspire.Hosting.AppHost, the DCP orchestrator and the dashboard. With Aspire.Hosting at 13.4.6 and DCP still at 13.1.2, DCP refuses to start. Bumped to 13.4.6 with a comment recording the lockstep requirement.

This only shows up at runtimedotnet build and the whole test suite passed while the fleet was completely broken. Worth knowing for future Aspire bumps.

Test tooling upgraded too (second commit)

The dev-tooling majors, now done and verified — build/test-time only, nothing here ships in a host:

  • Microsoft.NET.Test.Sdk 17.14.118.8.1
  • xunit.runner.visualstudio 2.8.23.1.5 (the v3 runner supports the xunit 2.9.3 core we use)
  • NSubstitute 5.3.06.0.0

Shouldly (4.3.0), xunit (2.9.3) and ArchUnitNET (0.13.3) were already current.

NSubstitute 6 changed the nullability annotation on Arg.Is<T>'s predicate — the lambda parameter
is now T? — surfacing four new CS8602/CS8604 warnings. Fixed with explicit null guards rather
than !, so a null argument fails the Received() assertion with NSubstitute's own message instead of
throwing an NRE inside the matcher.

A test-runner major can break trait filtering, which is exactly what separates our two build
targets
, so both directions were verified:

Result
./build.sh Test 125 tests, Live correctly excluded (9s)
./build.sh TestLive 16/16 Live tests correctly included — real ARD/ZDF network downloads green (6m6s)

Also corrected a prerequisite I got wrong in the README rewrite: it told readers to run
dotnet workload install aspire. That is legacy — Aspire 13 arrives via the Aspire.AppHost.Sdk
reference plus NuGet. Confirmed empirically: this machine has no workloads installed at all and the
fleet starts fine.

global.json deliberately left at 10.0.100 — with rollForward: latestMinor that is a floor, not a
pin (resolves to 10.0.302 locally). Raising it would only exclude contributors on an earlier 10.0.x
feature band.

Still deliberately NOT bumped

  • WolverineFx 5.18 → 6.22 — the messaging/mediator/outbox backbone. A major there deserves its own PR and its own testing.
  • Microsoft.Extensions.{ServiceDiscovery,Http.Resilience} 9.x → 10.8.0 — the only packages still on 9.x while everything else is 10.x, so worth doing, but they're majors that touch service discovery and HTTP resilience at runtime.

Testing

  • dotnet list package --vulnerable --include-transitiveclean on both the solution and build/_build.csproj.
  • Build: 0 warnings, 0 errors (SharpCompress 0.38 → 0.50 did not break the XZ parser API).
  • ./build.sh Test: Infra 67 / App 50 / Arch 8 green.
  • Fleet smoke-tested: dotnet run --project AppHost — DCP created the Postgres container and started all five long-running hosts (newznab, web, agent-ard, agent-zdf, agent-downloader), with the run-to-completion migrator finishing first.

⚠️ Fallout regenerated the CI workflow — please review that diff closely

.github/workflows/build.yml (and .fallout/build.schema.json) are Fallout-generated, and bumping to
10.4.0-rc.4 regenerated them as a side effect of running the build. I did not hand-edit either.
The workflow change is not cosmetic:

-      - uses: actions/checkout@v6
+      - uses: actions/checkout@v7
-        uses: actions/cache@v4
+        uses: actions/cache@v6
+      - name: 'Setup: .NET SDK'
+        uses: actions/setup-dotnet@v6
+        with:
+          global-json-file: global.json
+      - name: 'Restore: dotnet tools'
+        run: dotnet tool restore
-      - run: ./build.cmd Test
+      - run: dotnet fallout Test

The last line matters: CI now invokes the Fallout global tool instead of ./build.cmd. That tool is
pinned to 10.3.49 in .config/dotnet-tools.json and cannot be bumped — 10.4.0-rc.4 of
fallout.globaltool is not on nuget.org.
So as of this PR, CI runs the 10.3.49 tool against a
_build.csproj that references 10.4.0-rc.4 packages.

Resolved empirically: the skew is fine. CI passed and the log confirms it genuinely ran the old tool
against the new packages:

Tool 'fallout.globaltool' (version '10.3.49') was restored.
Run dotnet fallout Test

So this is not a blocker. fallout.globaltool has no 10.4.x on nuget.org (latest is 10.3.49), so
.config/dotnet-tools.json stays put — publish the tool at 10.4.0-rc.4 and it can follow in a one-line
change.

Two further notes for the reviewer

  1. fallout.globaltool stays at 10.3.49 in .config/dotnet-tools.json — there is no 10.4.0-rc.4 of the global tool on nuget.org. It is not in the build path (build.sh runs dotnet run against _build.csproj directly); it is only used for fallout --generate-configuration. So there is now a tool/package skew that could regenerate a stale CI workflow. Publish the tool at 10.4.0-rc.4 and this can follow.
  2. Aspire 13.4.6 defaults the dev Postgres container to postgres:18.3 (was 17.x). Dev data is ephemeral so it is harmless, but the Testcontainers fixture pins postgres:17-alpine and could be aligned so tests match dev.

🤖 Generated with Claude Code

ChrisonSimtian and others added 2 commits July 27, 2026 10:55
…patches

A full `dotnet list package --vulnerable --include-transitive` showed five
advisories, not the one visible in build warnings — the rest were being lost in
warning noise. All are now clear across the solution and the build project.

Security:
- OpenTelemetry 1.11.x -> 1.17.0 (Prometheus exporter 1.10.0-beta.1 ->
  1.17.0-beta.1 to stay in step). GHSA-g94r-2vxg-569j + GHSA-4625-4j76-fww9.
  Highest-impact of the set: ServiceDefaults is referenced by every host, so
  this shipped everywhere.
- SharpCompress 0.38.0 -> 0.50.1. GHSA-6c8g-7p36-r338. Interim fix — its only
  consumer is the dead MediathekView parser that #49 removes outright.
- Aspire.Hosting* 13.1.2 -> 13.4.6, which drops the StreamJsonRpc that carried
  MessagePack 2.5.192. GHSA-hv8m-jj95-wg3x.
- Fallout.Common/Components 10.3.49 -> 10.4.0-rc.4, picking up Microsoft.Build
  18.0.2 and clearing the five System.Security.Cryptography.Xml advisories on
  the Nuke build project.

Servicing patches, same major (no API surface change):
- EF Core + Design + SqlServer 10.0.4 -> 10.0.10
- Microsoft.Extensions.{Hosting.Abstractions,Configuration.Binder,Http} and
  Microsoft.AspNetCore.OpenApi 10.0.0 -> 10.0.10
- Riok.Mapperly 4.1.1 -> 4.3.1

The Aspire bump needed a second change to work. `Aspire.AppHost.Sdk` in
Krautwatch.AppHost.csproj separately pins Aspire.Hosting.AppHost, the DCP
orchestrator and the dashboard; leaving it at 13.1.2 while Aspire.Hosting moved
to 13.4.6 made DCP refuse to start outright ("Newer version of the
Aspire.Hosting.AppHost package is required"). Bumped to 13.4.6 with a comment so
the lockstep requirement is not rediscovered the hard way.

Deliberately NOT bumped — majors wanting their own PR and real testing:
WolverineFx 5.18 -> 6.22 (the messaging/outbox backbone), NSubstitute 5 -> 6,
Microsoft.NET.Test.Sdk 17 -> 18, xunit.runner.visualstudio 2 -> 3, and
Microsoft.Extensions.{ServiceDiscovery,Http.Resilience} 9.x -> 10.8.0.

Verified: `dotnet list package --vulnerable --include-transitive` clean on both
the solution and build/_build.csproj. Build is 0 warnings / 0 errors. Tests green
(Infra 67 / App 50 / Arch 8). `dotnet run --project AppHost` brings the fleet up
— DCP created the Postgres container and started all five long-running hosts,
with the run-to-completion migrator finishing first.

Note: Aspire 13.4.6 defaults the dev Postgres container to postgres:18.3 (was
17.x). Dev data is ephemeral so this is harmless, but our Testcontainers fixture
pins postgres:17-alpine and could be aligned.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Takes the three dev-tooling majors held back from the previous commit. These are
build/test-time only — nothing here ships in a host:

- Microsoft.NET.Test.Sdk        17.14.1 -> 18.8.1
- xunit.runner.visualstudio     2.8.2   -> 3.1.5   (the v3 runner supports the
                                                    xunit 2.9.3 core we use)
- NSubstitute                   5.3.0   -> 6.0.0

Shouldly (4.3.0), xunit (2.9.3) and ArchUnitNET (0.13.3) were already current.

NSubstitute 6 changed the nullability annotation on Arg.Is<T>'s predicate — the
lambda parameter is now T? — which surfaced four new CS8602/CS8604 warnings in
Application.Tests. Fixed with explicit null guards rather than the null-forgiving
operator, so a null argument fails the Received() assertion with NSubstitute's own
message instead of throwing an NRE inside the matcher.

Verified the test-runner major did not break trait filtering, which is what
separates the two build targets:
- ./build.sh Test     -> 125 tests, Live correctly EXCLUDED (9s)
- ./build.sh TestLive -> 16/16 Live tests, correctly INCLUDED, real ARD/ZDF
                         network downloads green (6m6s)

Build is back to 0 warnings / 0 errors.

Also corrected a prerequisite I got wrong in the README rewrite: it told readers to
run `dotnet workload install aspire`. That is legacy — Aspire 13 arrives via the
Aspire.AppHost.Sdk reference plus NuGet packages. Confirmed empirically: this
machine has NO workloads installed and the fleet starts fine.

global.json is deliberately left at 10.0.100 — with rollForward latestMinor that is
a floor, not a pin (it resolves to 10.0.302 here). Raising it would only exclude
contributors on an earlier 10.0.x feature band for no gain.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ChrisonSimtian ChrisonSimtian changed the title chore(deps): clear all five package advisories + .NET 10 servicing patches chore(deps): clear all five package advisories, .NET 10 servicing patches, and test-tooling majors Jul 26, 2026
@ChrisonSimtian
ChrisonSimtian merged commit e383a21 into main Jul 26, 2026
1 check passed
@ChrisonSimtian
ChrisonSimtian deleted the chore/dependency-security-bumps branch July 26, 2026 23:34
ChrisonSimtian added a commit that referenced this pull request Jul 27, 2026
…ery-driven

DR-010 stated that polling each Sonarr/Radarr instance for its monitored series
"is the crawl work-list". That made the monitored list load-bearing: #6 was scoped
as the work-list, #12 was blocked behind it, and #4/#48 became prerequisites for
basic indexing. Before building it, checked how the comparable projects solve the
same problem.

Neither does it this way:

- MediathekArr keeps no catalog at all. It is a live search proxy — "pretending to
  be a usenet indexer, but actually just fetching and parsing search results from
  MediathekViewWeb", with TVDB for metadata and the real effort in matching.
- RundfunkArr uses curated configuration: data/shows.json plus data/rulesets.json
  (Mediathek topic, filters, season/episode regex), extended by community PRs.

Neither reads Sonarr's monitored series via the Sonarr API, because the Newznab
contract is pull-by-query: Sonarr already knows what it monitors and asks for
exactly what it wants. An indexer is not supposed to know the monitored list.

The reason the question arose for us is our own choice, not a property of being an
*arr indexer: DR-010 de-emphasised MediathekView in favour of the direct ARD/ZDF
APIs. MediathekViewWeb is effectively a complete dump, so MediathekArr gets breadth
free; our ARD crawler must walk A-Z catalog -> show page -> episodes -> item page and
therefore has to be told which shows to walk. The work-list problem is self-inflicted
by the direct-API decision.

DR-011 accordingly:
- Search becomes query-driven (resolve on demand, cache), so any show works without
  pre-registration.
- The standing crawl list survives only as RSS-feed input, since RSS-Sync genuinely
  needs a recent-releases list.
- Reach-back is demoted to an optional pre-warm. Nothing may depend on a configured
  *arr instance to function.
- Matching (EpisodeNumbering, SeriesType, the unset Show.TvdbId) is where the effort
  belongs, since that is where both comparables concentrate.

Reach-back was also insufficient on its own: an interactive search for a show that is
unmonitored, or monitored but not yet crawled, returns nothing — so a query-driven
path was needed regardless, which demotes reach-back by definition.

DR-010's clause is struck through in place rather than deleted, so the history stays
readable, and its header records the retraction. CLAUDE.md stated the retracted claim
as fact and is corrected.

Recorded honestly in the DR: MediathekArr's README does not explicitly say
live-versus-cached (inferred), and neither project documents RSS support — which is
exactly the half that still needs a standing crawl, so our RSS design cannot be copied
from either.

Backlog: #6 re-scoped to an optional pre-warm and unblocked from #12; #58 opened for
query-driven search; #49 (delete MediathekView) put on hold — its SharpCompress
advisory was already fixed by a version bump in #53, and the filmliste is the only
full-catalog source available, which is precisely what MediathekArr depends on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant