v0.21.0
This release focuses on API surface hardening, GB300 and Vera Rubin support, major GPU Operator and Dynamo version bumps, and Kubernetes 1.37 with broad validation and bundler hardening.
Highlights
New Hardware and Platform Support - GB300 lands on both the cloud and bare-metal (NCP) paths: a generic gb300-generic-ubuntu-training recipe for self-managed Kubernetes (#2568), EKS training and inference recipes (#2382) with signed evidence (#2410), and a Slurm variant (#2544). Vera Rubin (VR200) arrives as preview overlays on RKE2 (#2520), with published evidence (#2573).
Component Upgrades - GPU Operator moves to v26.7.0 and the DRA driver to 0.5.0, with a workaround for the ComputeDomain CRD conflict v26.7.0 introduces and the driver held at 580 (#2439). dynamo-platform moves to 1.4.2: the request plane defaults to TCP and KV events to ZMQ, so bundled NATS is no longer deployed - re-enabling it is opt-in for standing clusters. The same bump takes Grove to v0.1.0-alpha.12 and picks up a NIXL loader-path fix (#1983).
Recipes and Coverage
- GKE self-installed driver pools now carry the driver in the bundle:
gpuStack=bundle-installerreplacesdriver-installer, pinning the version in the recipe so upgrades roll with the bundle (#2360) - OKE gains a
gpuStackprofile (#2355), with RDMA fabric wiring for L40S RoCE and GB200 InfiniBand landing alongside it (#2356) - An
l40-anyaccelerator overlay and a declared RTX PRO 6000 Server Edition driver floor - Per-value readiness constraints for configuration profiles
Validation Hardening - Every NCCL benchmark run gets its own namespace, and cleanup fails the run when that namespace will not terminate. The validator rejects an incompatible StorageClass before creating the model-cache PVC, tolerates tainted nodes with a wider Trainer readiness timeout, retries transient reads while polling gang-scheduling pods, and resolves the GPU-node universe label per service. DaemonSet checks are guarded against stale rollouts, and concurrent snapshot runs no longer collide.
API Surface Hardening - The four surfaces AICR freezes for v1 - REST, Go SDK, CLI, and artifact schemas - are now each held to a committed baseline. The profile-aware /v2 REST family folds into a single /v1 (#2112) - a pre-adoption restructure with no consumers to notify. JSON Schemas for the v1 artifacts are published and gated, the per-deployer bundle layout is frozen, and artifacts read both their alpha apiVersion and the maturity-appropriate target from ADR-022. pkg/client/v1 is now the only path the CLI and server take into business logic, enforced by an architecture test. Backing all of it: gates that replay documented REST examples and CLI invocations against real handlers and assert the spec and server agree on routes.
Bundler and Deployer Reliability - A readiness gate landed for the Helm network-operator, DRA eviction is wired for GPU driver upgrades behind an opt-in node label, and OCP gates the GPU Operator on network readiness. Bundles missing a required node selector now fail instead of shipping, generated wrappers are stamped with both the AICR and payload versions, and Argo CD is forced to replace the readiness-gate Job on upgrade.
Other Improvements - Kubernetes moves to 1.37: recipe floors are raised to clear the DRA chart's kubeVersion, agentgateway moves to v1.5.0 for the tightened CRD cost budget, client libraries are on v0.37.0, and Kind and KWOK lanes run 1.37 with Argo CD server-side diff. Toolchain moves to Go 1.27.1.
CycloneDX SBOMs and OpenVEX documents are published per platform, and vendor/ is gone in favor of Go proxy resolution verified reproducible on every push to main (ADR-023), and ADR-025 proposes an NVIDIA Cluster Readiness Engine component.
Thanks to @atif1996, @ayuskauskas, @ezhang3333, @framsouza, @giuliocalzo, @haarchri, @Kevin-Hawkins, @lalitadithya, @lockwobr, @MDhamani, @mikecook, @mohityadav8, @njhensley, @ntheanh201, @rorajani, @srao-nv, @varmesh, @xdu31, @yankay, @yuanchen8911, and @mchmarny.
Changelog
New Features
- dc3818e: feat(agent): isolate concurrent snapshot runs with per-run resources (#2357) (@ayuskauskas)
- d380113: feat(api)!: collapse the REST families into a single /v1 (#2464) (@mchmarny)
- 54f31b4: feat(api): deprecation channel, CLI surface gate, ADR-022 emit guards (#2436) (@mchmarny)
- 3f70c95: feat(api): gate the REST contract against a committed baseline (#2468) (@mchmarny)
- 482f670: feat(api): publish and gate JSON Schemas for the v1 artifacts (#2470) (@mchmarny)
- 05b75b7: feat(bundler): add readiness gate for the Helm network-operator (#2337) (@framsouza)
- d85b4ba: feat(bundler): freeze the per-deployer bundle layout (#2475) (@mchmarny)
- cefd89d: feat(bundler): wire DRA eviction for GPU driver upgrades (#2401) (@MDhamani)
- 3e8bef2: feat(recipe): per-value readiness constraints for configuration profiles (#2347) (@atif1996)
- 33f0860: feat(recipes)!: GKE bundle-installer replaces driver-installer (#2360) (@atif1996)
- ffe0cc2: feat(recipes): OKE RDMA fabric wiring (L40S RoCE + GB200 IB) (#2356) (@atif1996)
- e08293b: feat(recipes): add GB300 EKS Ubuntu training Slurm recipe (#2544) (@varmesh)
- de6514b: feat(recipes): add GB300 EKS training and inference overlays (#2382) (@yuanchen8911)
- bb0b059: feat(recipes): add VR200 (Vera Rubin) RKE2 preview overlays (#2520) (@yuanchen8911)
- bf36a91: feat(recipes): add l40-any accelerator overlay (#2366) (@ntheanh201)
- 432f597: feat(recipes): declare RTX PRO 6000 Server Edition driver floor (#2446) (@yuanchen8911)
- 83ce737: feat(recipes): generic bare-metal GB300 training recipe (#2568) (@atif1996)
- 0cf961f: feat(recipes): gpuStack profile for the OKE family (#2355) (@atif1996)
- a874184: feat(recipes): register nvcre Helm component (#2524) (@rorajani)
- 4e8a1c9: feat(sdk): complete the facade surface for snapshot criteria and mirror inventory (#2478) (@mchmarny)
- aa337f3: feat(sdk): derive CollectSnapshot AgentConfig from spec.snapshot (#2538) (@mchmarny)
- 245b693: feat(sdk): derive bundle and validate options from AICRConfig (#2521) (@mchmarny)
- 949f672: feat(sdk): derive evidence attestation options from AICRConfig (#2542) (@mchmarny)
- 84983e8: feat(sdk): migrate pkg/cli off pkg/config onto the aicr.Config facade (#2548) (@mchmarny)
- 31ee1a3: feat: accept target artifact versions defined by ADR-022 (#2404) (@mchmarny)
Bug Fixes
- a9a1be6: fix(api)!: accept HEAD and make GET and POST echo the same criteria (#2472) (@mchmarny)
- e312609: fix(api): stage ADR-022 default-track target in recipe response enums (#2419) (@mchmarny)
- d961042: fix(bundler): force ArgoCD replace on readiness-gate Job upgrade (#2408) (@Kevin-Hawkins)
- f71bd8b: fix(bundler): make the DRA eviction node label opt-in (#2471) (@yuanchen8911)
- 7469fdb: fix(bundler): stamp AICR and payload versions into generated wrappers (#2571) (@mchmarny)
- 3bc6a10: fix(bundler): stop Argo CD from flipping computedomains CRD ownership (#2547) (@yuanchen8911)
- 315463d: fix(bundler): warn when GPU nodes lack the DRA kubelet-plugin label (#2457) (@yuanchen8911)
- a455a93: fix(chainsaw): guard DaemonSet health checks against stale rollouts (#2453) (@mikecook)
- bea09a3: fix(ci): enable Argo CD server-side diff for k8s 1.37 KWOK lanes (#2603) (@rorajani)
- d4bf52e: fix(ci): extend api-diff package load timeout (#2399) (@yuanchen8911)
- 46b5764: fix(ci): install pinned E2E tools instead of runner defaults (@mchmarny)
- dab6f81: fix(ci): preload KWOK registry and Gitea images into the Kind node (#2480) (@mchmarny)
- ca8556c: fix(ci): pull the KWOK images once per run instead of once per job (#2497) (@mchmarny)
- e83c15d: fix(ci): refresh helm-diff checksums for v3.15.12 (#2545) (@rorajani)
- 147536b: fix(ci): spend the whole preload budget retrying a throttled pull (#2496) (@mchmarny)
- 912fe7c: fix(cli): correct migration guidance and close two surface-gate gaps (#2450) (@mchmarny)
- 688b04c: fix(constraints): resolve GPU-node universe label per service (#2554) (@framsouza)
- b6b2420: fix(docs): resolve post-merge review findings from #2436 (@mchmarny)
- 1bcad5d: fix(kwok): capture pod diagnostics before KWOK cleanup teardown (#2549) (@yuanchen8911)
- a27a953: fix(kwok): decouple presence check from the budget (#2510) (@varmesh)
- 761694b: fix(licenses): disclose 31 dependencies missing from THIRD_PARTY_NOTICES (#2384) (@mchmarny)
- 751cf38: fix(mirror): enforce Helm render version floor (#2435) (@yankay)
- 2897093: fix(recipes): address VR200/RKE2 review follow-ups from #2520 (#2589) (@yuanchen8911)
- 68c031f: fix(recipes): bump agentgateway to v1.5.0 for k8s 1.37 CRD cost budget (#2587) (@mchmarny)
- 7988e78: fix(recipes): gate OCP GPU operator on network readiness (#2503) (@MDhamani)
- 17b3376: fix(recipes): installer health check must assert a label Helm 4 keeps (#2444) (@atif1996)
- 744faca: fix(recipes): raise K8s floors to clear the DRA chart's kubeVersion (#2449) (@yuanchen8911)
- 2d5ea46: fix(recipes): roll nodewright-operator back to v0.17.1; qualify hook image for OKE (#2633) (@atif1996)
- f74241f: fix(sdk)!: guard the Client boundary and stop leaking a bundler type (@mchmarny)
- 68f1890: fix(sdk): close three input-handling gaps in the v1 facade (#2479) (@mchmarny)
- 330a146: fix(security): bump aiperf-bench base to distroless python 3.13-v4.1.2 (#2556) (@mchmarny)
- 56f84ae: fix(security): bump aiperf-bench base, add openssl VEX statements (@mchmarny)
- df024c7: fix(server): structured 405 on /metrics, allow HEAD, derive the route set (#2461) (@mchmarny)
- 03bd0dd: fix(snapshot): honor --format on the agent Job delivery path (#2414) (@giuliocalzo)
- 318cb6b: fix(tests): derive release script network timeout from script budget (#2413) (@mikecook)
- 51ba472: fix(tests): pass --storage-class in recipe-overlays smoke test (#2504) (@mikecook)
- 3d1402a: fix(tools): enforce pinned versions in tools-check (#2387) (@yuanchen8911)
- 36f52ec: fix(tools): remap moved cel-go repo so release notices resolve (@mchmarny)
- 564c598: fix(tools): track indented MDX code fences (#2329) (@varmesh)
- bf610a5: fix(validator): fail NCCL cleanup on namespace termination timeout (#2588) (@mikecook)
- d76b43d: fix(validator): harden Trainer controller toleration handling (#2460) (@mikecook)
- 4088299: fix(validator): isolate each NCCL benchmark run in its own namespace (#2443) (@mikecook)
- 1a1b583: fix(validator): reject incompatible StorageClass before model-cache PVC create (#2452) (@mikecook)
- a792a9a: fix(validator): tolerate taints, widen Trainer readiness timeout (#2445) (@mikecook)
- 24b8ea7: fix(validators): pair the TCPXO sidecar with the installer AICR ships (#2379) (@yuanchen8911)
- d52373f: fix(validators): remove the dead KAI Queue lifecycle from inference-perf (#2394) (@yuanchen8911)
- 19150cf: fix(validators): retry transient reads while polling gang test pods (#2407) (@yuanchen8911)
- fc99fd9: fix: gang-scheduling conformance on gb200 Dynamo leaves (#2395) (@yuanchen8911)
- 6a58536: fix: use jobset.install for kubeflow-trainer JobSet dependency (#2393) (@varmesh)
Other Tasks
- 2ed59ed: build(release): generate THIRD_PARTY_NOTICES.md at release time (#2511) (@mchmarny)
- 477e807: chore!: remove vendor/ and resolve dependencies through the Go proxy (#2388) (@mchmarny)
- fbc0ed6: chore(ci): add srao-nv to copy-pr-bot additional trustees (#2354) (@srao-nv)
- 66a0d45: chore(deps): Update Terraform google to v8 (#2495) (@github-actions[bot])
- 72e5aee: chore(deps): Update dependency anchore/grype to v0.118.0 (#2491) (@github-actions[bot])
- bb31e04: chore(deps): Update dependency anchore/syft to v1.51.1 (#2579) (@github-actions[bot])
- 291649b: chore(deps): Update dependency databus23/helm-diff to v3.15.12 (#2539) (@github-actions[bot])
- 16f0ca5: chore(deps): Update dependency go to v1.27.1 (#2580) (@github-actions[bot])
- c17d0d7: chore(deps): Update dependency golangci/golangci-lint to v2.13.2 (#2581) (@github-actions[bot])
- dac7ed9: chore(deps): Update dependency google/go-containerregistry to v0.22.0 (#2492) (@github-actions[bot])
- a17f5da: chore(deps): Update dependency kubernetes-sigs/karpenter to v1.14.1 (#2368) (@github-actions[bot])
- be9d178: chore(deps): Update dependency mikefarah/yq to v4.53.6 (#2433) (@github-actions[bot])
- e0f1b0b: chore(deps): Update dependency oasdiff/oasdiff to v1.30.0 (#2553) (@github-actions[bot])
- 1dcd731: chore(deps): Update kindest/node Docker tag to v1.37.0 (#2583) (@github-actions[bot])
- 16a590b: chore(deps): Update kubernetes to v0.37.0 (#2493) (@github-actions[bot])
- 527471c: chore(deps): Update ministackorg/ministack Docker tag to v1.5.3 (#2508) (@github-actions[bot])
- 430e3bc: chore(deps): Update ministackorg/ministack Docker tag to v1.5.7 (#2600) (@github-actions[bot])
- ee5f6ec: chore(deps): Update ministackorg/ministack Docker tag to v1.5.8 (#2608) (@github-actions[bot])
- 6de32cd: chore(deps): Update module golang.org/x/exp to v0.0.0-20260824195058-e88cd73687aa (#2434) (@github-actions[bot])
- 94166a9: chore(deps): Update testing-tools (#2412) (@github-actions[bot])
- 8bc6a75: chore(deps): Update testing-tools (#2490) (@github-actions[bot])
- 7ecf947: chore(deps): Update testing-tools (#2582) (@github-actions[bot])
- 68ab893: chore(deps): upgrade modules, tool pins, and coverage floor (@mchmarny)
- f32fd27: chore(dynamo-platform): coordinate NATS removal with Dynamo 1.4+ bump (#1983) (@mohityadav8)
- c94cf7e: chore(evidence): publish GB300 EKS training and inference attestations (#2410) (@yuanchen8911)
- 534a9f5: chore(fern): register v0.20.0 (#2361) (@github-actions[bot])
- a3075b0: chore(make): add update-goldens target for golden fixture regeneration (#2455) (@mikecook)
- 17163cc: chore(recipes): bump gpu-operator v26.7.0, DRA 0.5.0; hold driver 580 (#2439) (@yuanchen8911)
- 6849022: chore(uat): retire stale NATS 4222 ingress rules (#2558) (@varmesh)
- 142390f: chore: add mikecook to copy-pr-bot trustees (#2409) (@mikecook)
- 4a7c1f7: chore: deps: bump actions/cache from 5.0.3 to 6.1.0 (#2507) (@dependabot[bot])
- 9e45123: chore: deps: bump actions/deploy-pages from 5.0.0 to 5.0.1 (#2578) (@dependabot[bot])
- 4ac50fc: chore: deps: bump actions/setup-go from 6.2.0 to 7.0.0 (#2391) (@dependabot[bot])
- 48047ba: chore: deps: bump anchore/scan-action from 7.4.0 to 7.4.2 (#2488) (@dependabot[bot])
- 616745f: chore: deps: bump aws-actions/configure-aws-credentials from 6.2.3 to 6.2.4 (#2551) (@dependabot[bot])
- ee502dd: chore: deps: bump azure/login from 3.0.1 to 3.0.2 (#2489) (@dependabot[bot])
- bd10012: chore: deps: bump docker/setup-qemu-action from 4.2.0 to 4.3.0 (#2577) (@dependabot[bot])
- 0059386: chore: deps: bump renovatebot/github-action from 46.2.2 to 46.2.4 (#2411) (@dependabot[bot])
- 787a791: chore: deps: bump renovatebot/github-action from 46.2.4 to 46.2.5 (#2552) (@dependabot[bot])
- b82ebc2: chore: deps: bump the codeql-action group with 3 updates (#2487) (@dependabot[bot])
- b91f726: chore: refresh THIRD_PARTY_NOTICES.md for the k8s 0.37.0 bump (#2505) (@yuanchen8911)
- 9ce90f3: chore: remove dead pkg/build AICRRuntime build spec (#2371) (@mchmarny)
- 883085b: chore: run the go modernization tool (#2396) (@lalitadithya)
- 3faf301: ci(uat): remove AWS GB200 nightly UAT reservation entry (#2365) (@njhensley)
- 7275db8: ci: add a dispatch-only DGXC Go proxy probe (@mchmarny)
- 702e58e: ci: bump EKS UAT actuator image to v0.5.1 (#2425) (@njhensley)
- 341093a: ci: enforce the DGXC Go proxy, closing the fallthrough gap (#2376) (@mchmarny)
- bd9be36: ci: measure the resolver posture the goproxy action leaves behind (@mchmarny)
- 32f80f8: ci: pin setup-envtest and gate go.mod/go.sum tidiness (@mchmarny)
- abfa7b2: ci: run the depproxy kit digest gate in CI, not only locally (@mchmarny)
- b07dc0d: ci: scope the goproxy probe download to what the build needs (@mchmarny)
- c8f2e5a: ci: skip the hourly Rekor monitor in forks (#2557) (@haarchri)
- de93534: ci: vendor the DGXC Go proxy adoption kit with a digest gate (@mchmarny)
- 270278c: ci: verify vendor is reproducible from Artifactory on every main push (@mchmarny)
- 228bd23: docs(adr): propose ADR-025 NVIDIA Cluster Readiness Engine component (#2541) (@xdu31)
- 846442c: docs(agents): add code comment style guidance (#2574) (@atif1996)
- 38a0d9b: docs(evidence): add VR200/RKE2 training and inference-dynamo evidence (#2573) (@yuanchen8911)
- abafc18: docs(releasing): record that the deprecation channel ships unexercised (@mchmarny)
- 1743160: docs(roadmap): focus v1 on stability and coverage (@mchmarny)
- 5cda08f: docs(sdk): reconcile the integrator guide and add a runnable example (#2565) (@mchmarny)
- f735c58: docs(sdk): scope the evidence-options security rationale to the artifact (#2543) (@mchmarny)
- 58c0cb0: docs(user): document the machine type each accelerator criterion targets (#2380) (@yuanchen8911)
- 71b3a95: feat(supply-chain): publish CycloneDX SBOM and OpenVEX per platform (#2518) (@lockwobr)
- 6f73aac: fix(recipe/bundler): fail bundles missing a required node selector (#2570) (@mikecook)
- 6e27ef9: refactor(header): give each ADR-022 schema track its own emitter constant (#2420) (@mchmarny)
- dbca92d: style(api): match sibling enum style and reflow the /v1 legacy paragraph (#2422) (@mchmarny)
- 6452555: test(api): assert the OpenAPI spec and the server agree on routes (#2448) (@mchmarny)
- 2bd99d1: test(api): replay documented REST examples against a real handler (#2466) (@mchmarny)
- fdde92b: test(architecture): gate cli and server on the pkg/client/v1 facade (#2559) (@mchmarny)
- faafa5d: test(bundler): assert the DRA node-label warning count, not just its presence (#2465) (@yuanchen8911)
- dcad82b: test(cli): cover the urfave-injected CLI surface behaviorally (#2463) (@mchmarny)
- c94ee11: test(cli): gate documented CLI invocations against the surface baseline (#2462) (@mchmarny)
- b49848f: test(e2e): remove always-passing assertions (#2415) (@varmesh)
- 6335426: test(sdk): gate the examples table against the code (#2575) (@ezhang3333)
- 2baf43a: test(uat): re-enable GCP serve phase by pinning Frontend to GPU pool (#2233) (@rorajani)