chore: move hosts and shipped artifacts to .NET 10 LTS (SDK 10.0.1xx) [D4 assumed, CI-verified only] - #340
Merged
Merged
Conversation
Why: .NET 9 (STS) left support in May 2026 and .NET 8 LTS ends in November 2026; .NET 10 is the current LTS. The repo still pinned SDK 9.0.100, shipped net8.0 hosts and images on aspnet:8.0, and ran the net9-only in-process API tests on a framework that is out of support. What changes (D4 assumed - owner to confirm): - global.json pins sdk 10.0.100 (rollForward latestFeature). The C# 12 LangVersion pin stays; its rationale (OverloadResolutionPriority vs FluentAssertions 8) holds for the C# 14 compiler too. - Hosts and shipped executables (Nexo.CLI, Nexo.Mcp.Server.Host, Nexo.Transport.Grpc.Server.Host, ValidationUtilities, tools/*, the first-flight spike) target net10.0. Nexo.Tests.CLI follows the CLI. - Libraries multi-target net8.0;net10.0 so the net8 consumer story stays alive until Nov 2026; netstandard2.0 contracts become netstandard2.0;net8.0;net10.0 (Brick.Contracts keeps net8.0 for the generated bricks). Test projects move net8.0;net9.0 -> net8.0;net10.0; the VirtualProduction / A2A TestServer suites are net10.0-only with the 10.0.11 Mvc.Testing / TestHost override. - Nexo.API multi-targets net8.0;net10.0 rather than net10.0-only: it is consumed as a library by the net8.0 inner build of Nexo.Tests.Infrastructure (Tests/API) and by the commercial hosts (out of scope). The images publish -f net10.0 and every `dotnet run --project application/src/Nexo.API` now passes -f net10.0. - Nexo.BackgroundAgents.HostRunners is a library (no OutputType), so it multi-targets like the other libraries instead of net10.0-only. - Dockerfiles: sdk:10.0 / aspnet:10.0; agent-server no longer installs the 8.0 runtime; the test images build the net10.0 inner builds and keep the 8.0 runtime only for the net8.0 test hosts. fleet-host and game-director keep an 8.0 runtime stage for the commercial net8.0 hosts. - Dev container / container bootstrap / setup scripts / verify matrix move to the 10.0 images (sdk:10.0-noble replaces 9.0-bookworm-slim: MCR publishes no Debian variant for sdk:10.0) and require SDK 10. - Session candidate build / execution runner (SessionCandidateBuild, SessionExecutionBackend) generate net10.0 projects: reference assemblies streamed from a net10.0 host cannot compile against net9.0 (CS1705), so the in-session TFM has to follow the host TFM. - Gate scripts that ran Nexo.Tests.CLI with -f net8.0 use -f net10.0; scripts running the multi-target suites keep -f net8.0 on purpose. - Two SYSLIB0057 obsoletions surfaced by the net10.0 inner builds are handled minimally: DER bytes go through X509CertificateLoader on NET9_0_OR_GREATER; the file-path loader in the gRPC channel factory is kept (it is the only auto-detecting PFX/DER/PEM loader) under a pragma. Skipped on inspection: Directory.Packages.props ASP.NET pins stay at 8.0.0 because net8.0 consumers (net8 inner builds, commercial tests) still resolve them; the net10.0 consumers already use VersionOverride. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Why: global.json now pins SDK 10, so every setup-dotnet block that named 9.0.x moves to 10.0.x, and the lanes that only named 8.0.x (they built because the runner image happened to carry SDK 9) now install 10.0.x explicitly instead of depending on the image contents. 8.0.x stays only where a lane deliberately exercises the net8.0 outputs (cert-gate and the gate scripts run the multi-target suites -f net8.0; consumer/sample lanes build net8.0 consumers; single-target net8.0 test projects). CLI-only lanes (runtime-release-*, runtime-studio-forge-smoke, workflow-regression-gate) are 10.0.x only, and the full-platform-readiness native lane stays SDK-single at 10.0.x per wave 1. `-f net9.0` becomes `-f net10.0` (kernel-coverage, mcp-a2a, distribution matrix, production readiness, trust multi-env, readiness containers), the container matrices pass DOTNET_VERSION=10.0, and the ephemeral setup gate uses sdk:10.0 / sdk:10.0-noble (no Debian variant exists for sdk:10.0). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Why: README badge, prerequisites, GettingStarted, CONTRIBUTING, the IntegratorGuide compatibility matrix and DotnetVersions.md all said SDK 9 / net8.0 hosts. They now describe SDK 10 (LTS), net10.0 hosts, net8.0;net10.0 libraries, and the -f net10.0 needed to `dotnet run` the multi-targeted Nexo.API. Gate/testing docs that mirror workflow steps follow the workflow edits. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… restore
Why: the first CI cycle on SDK 10 failed at restore everywhere.
- NU1510 ("PackageReference X will not be pruned") is raised for the
audit-override references Directory.Build.props adds to every project
and for the 10.0.x central pins whenever the SDK's bundled runtime is
at least that patch - a condition that flips per SDK release. Suppress
the hint; pruning stays on.
- SDK 10 audits transitive packages by default, which surfaced SSH.NET
2025.1.0 (GHSA-q939-rpr3-3284) under Testcontainers. Both consumers
reference the patched 2026.0.0 directly (repo pattern for NU1903).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>…ndOfStream (CA2024) Why: the .NET 10 analyzers (AnalysisLevel=latest under SDK 10) flag StreamReader.EndOfStream inside async methods as CA2024, which is an error under TreatWarningsAsErrors and blocked every lane in CI cycle 2. ReadLineAsync returning null is the async end-of-stream signal; behaviour is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…defaults to .slnx) Why: the external-product-shape lane creates a consumer solution and then adds projects to ExternalProduct.sln; on SDK 10 'dotnet new sln' writes ExternalProduct.slnx by default, so the follow-up 'dotnet sln add' could not find the file. --format sln restores the previous behaviour. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Why: Nexo.Tests.CLI now targets net10.0 (it follows Nexo.CLI), so PublicApiGenerator reads the net10.0 build of Nexo.Authoring / Nexo.Sdk / Nexo.Framework.Sdk and the assembly-level TargetFramework attribute in the approved snapshots is v10.0 instead of v8.0. Only that line changes; the public surface itself is identical (full-platform-readiness Linux lane, 1/2967 tests). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
IanFrelinger
marked this pull request as ready for review
August 17, 2026 14:08
…ons, keep 10.0.x setup-dotnet, Orchestration csproj from this branch (master side was renormalization only)
…tatements updated to 10 (GettingStarted, IntegratorGuide, TesterQuickstart)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
[skip-prod-style] Rationale: no production wiring changes. The production-path diffs are TFM/
TargetFrameworksedits in.csprojfiles, an XML-doc/sdk:image string inNexo.Infrastructure(session build TFM), and two SYSLIB0057 obsoletion shims with unchanged behaviour; the ProdStyle / virtual-host suites themselves move tonet10.0and run in themcp-a2a-gate/distribution-matrix-gatelanes on this PR.Why
.NET 9 (STS) left support May 2026; .NET 8 LTS ends Nov 2026; .NET 10 LTS shipped Nov 2025. The repo pinned SDK 9.0.100, shipped net8.0 hosts on
aspnet:8.0, and ran the in-process API tests on net9.What
10.0.100,rollForward: latestFeature. C# 12LangVersionpin kept (rationale still holds on the C# 14 compiler).net10.0: Nexo.CLI, Nexo.Mcp.Server.Host, Nexo.Transport.Grpc.Server.Host, ValidationUtilities,tools/*, first-flight spike; Nexo.Tests.CLI follows the CLI.net8.0;net10.0;netstandard2.0contracts ->netstandard2.0;net8.0;net10.0(Brick.Contracts keeps net8.0 for generated bricks). Test projectsnet8.0;net9.0->net8.0;net10.0; VirtualProduction / A2A TestServer suites are net10-only withMvc.Testing/TestHostVersionOverride=10.0.11.net8.0;net10.0(not net10-only): consumed as a library by the net8.0 inner build ofNexo.Tests.Infrastructure(Tests/API/**) and by the commercial hosts (out of scope). Images publish-f net10.0; everydotnet run --project application/src/Nexo.APIin scripts/docs now passes-f net10.0.sdk:10.0/aspnet:10.0; agent-server drops its 8.0 runtime install; test images build-f net10.0and keep the 8.0 runtime only for the net8.0 test hosts; fleet-host/game-director keep an 8.0 runtime stage for the commercial net8.0 hosts.devcontainers/dotnet:10.0-noble,sdk:10.0(+sdk:10.0-noblewhere a second distro was probed - MCR publishes no Debian-bookworm-slim/-trixie-slimforsdk:10.0), setup scripts require SDK >= 10 and install channel 10.0 /Microsoft.DotNet.SDK.10.net10.0projects and the spike pinssdk:10.0(a net10.0 host streaming its reference assemblies into a net9.0 candidate would fail with CS1705).9.0.x->10.0.xeverywhere; 8.0.x-only lanes now install10.0.xexplicitly (they only built because the runner image carried SDK 9);8.0.xkept only where a lane deliberately exercises net8.0 outputs (cert-gate-f net8.0, gate scripts, consumer/sample lanes, single-target net8.0 test projects); CLI-only lanes and the full-platform-readiness native lane are10.0.xonly.-f net9.0->-f net10.0; container matrices passDOTNET_VERSION=10.0.X509CertificateLoaderunderNET9_0_OR_GREATERfor DER bytes; pragma + comment for the auto-detecting file-path loader in the gRPC channel factory).Skipped on inspection (with evidence)
Mvc.Testing,TestHost,OpenApi,JwtBearer,OpenIdConnect):Mvc.Testingis referenced by commercial net8.0 test projects and by the net8.0 inner build ofNexo.Tests.Infrastructure; a 10.0.x central pin cannot resolve for net8.0. net10 consumers already useVersionOverride=10.0.11. The other three are unreferenced.OutputType; referenced by Nexo.API's net8.0 build and Nexo.Tests.BackgroundAgents), so it multi-targets like the other libraries rather than going net10-only.docs/TesterQuickstart.mddoes not exist onorigin/master; not created here.Grep survivors (justified)
.docker/Dockerfile.fleet-hostaspnet:8.0runtime stage andDockerfile.game-director8.0 runtime install: commercial net8.0 hosts.Directory.Build.propscomment mentions net9.0 (LangVersion rationale);.docker/Dockerfile.agent-server,cross-platform-tests.yml,ValidationServiceAdapter.cscomments are historical.ValidationServiceAdapterGapCoverageTestsnet9.0strings are parser test data (generic TFM strings).8.0.xsetup-dotnet entries and-f net8.0gate scripts: deliberate net8 consumer lanes on multi-target suites.net8.0(consumer story).Verification
*.csproj/*.props/*.targetsload withSystem.Xml.XmlDocument; the WIP had left an invalid--inside a comment inNexo.API.csproj(fixed).net9.0|9.0.x|sdk:9.0|aspnet:8.0|SDK 9|channel 9.0over non-md files: only the justified list above.CI state (final head
c088bbf5)Four CI cycles were needed after the initial push (each was a real SDK-10 behaviour surfaced by CI, fixed minimally, one commit each):
7b5cfe46- restore failed everywhere: NU1510 (SDK 10 package pruning warns on the audit-override direct references / 10.0.x pins; suppressed viaNoWarn, pruning stays on) and NU1903 SSH.NET 2025.1.0 (SDK 10 audits transitive packages; Testcontainers consumers now reference SSH.NET 2026.0.0).d6f7ac1d- CA2024 (.NET 10 analyzer:StreamReader.EndOfStreamin an async method) inOllamaHttpChatClient; loop now reads tonull.252e4ec1-dotnet new slndefaults to.slnxon SDK 10; the external-product-shape script asks for--format sln.c088bbf5- the Nexo.Tests.CLI public-API snapshots embed the assemblyTargetFrameworkattribute; re-approved for v10.0 (1/2967 tests, surfaced by the full-platform-readiness Linux native lane).Green on
c088bbf5(pull_request): Cert gate, Kernel Gate, Kernel coverage gate, Application Gate, Security Gate, Distribution Matrix Gate (CLI/API images onsdk:10.0/aspnet:10.0, in-process Nexo.API on net10, external product shape, standalone brick scaffold, StableSdkHostSample pack), Core domain coverage, Provenance Graph CI, Testing strategy gate, dependency-boundary, layer-boundary, Docs Link Check, Shell lint.Green on
c088bbf5(dispatched): Full Platform Readiness Gate - all 11 jobs (Linux/macOS/Windows native on SDK 10 only, Ubuntu/Alpine/Debian containers, Docker CLI/API/agent-server/quickstart images).Green on
252e4ec1(dispatched; unchanged by the last commit, which only touched three snapshot files): MCP + A2A protocol gate (net10 TestServer suites), Dev Container Gate (devcontainers/dotnet:10.0-noble), Environment Setup Gate v1 (ubuntu/macos/windows + ephemeralsdk:10.0andsdk:10.0-noble), Production Readiness Gate v1 (3 OSes,-f net8.0+-f net10.0pipeline lanes), Container Image Gate, onboarding-quickstart-gate.Not run here: self-hosted / manual lanes (test-caching-multi-env, test-trust-multi-env, test-persistence-multi-os, cross-platform-tests, release lanes) - edited mechanically (
9.0.x->10.0.x,-f net9.0->-f net10.0,DOTNET_VERSION=10.0); nothing red remains on the lanes that ran.