---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index a72b1c3f4..195e89d39 100644
--- a/README.md
+++ b/README.md
@@ -58,7 +58,7 @@ We as members, contributors, and leaders pledge to make participation in our com
## Licensing
-Copyright 2024-2025 SAP SE. Please see our [LICENSE](LICENSE) for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available [via the REUSE tool](https://api.reuse.software/info/github.com/cobaltcore-dev/cortex).
+Copyright SAP SE. Please see our [LICENSE](LICENSE) for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available [via the REUSE tool](https://api.reuse.software/info/github.com/cobaltcore-dev/cortex).
From 51c773d9dc8c96d491c039cc6be80f70acf646cb Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Mon, 27 Jul 2026 08:52:01 +0200
Subject: [PATCH 04/11] Renovate: Update External dependencies (#1090)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This PR contains the following updates:
| Package | Change |
[Age](https://docs.renovatebot.com/merge-confidence/) |
[Adoption](https://docs.renovatebot.com/merge-confidence/) |
[Passing](https://docs.renovatebot.com/merge-confidence/) |
[Confidence](https://docs.renovatebot.com/merge-confidence/) | Type |
Update |
|---|---|---|---|---|---|---|---|
|
[github.com/prometheus/client_golang](https://redirect.github.com/prometheus/client_golang)
| `v1.24.0` β `v1.24.1` |

|

|

|

| require | patch |
|
[kube-prometheus-stack](https://redirect.github.com/prometheus-operator/kube-prometheus)
([source](https://redirect.github.com/prometheus-community/helm-charts))
| `87.19.0` β `87.19.2` |

|

|

|

| | patch |
---
### Release Notes
prometheus/client_golang
(github.com/prometheus/client_golang)
###
[`v1.24.1`](https://redirect.github.com/prometheus/client_golang/compare/v1.24.0...v1.24.1)
[Compare
Source](https://redirect.github.com/prometheus/client_golang/compare/v1.24.0...v1.24.1)
prometheus-community/helm-charts
(kube-prometheus-stack)
###
[`v87.19.2`](https://redirect.github.com/prometheus-community/helm-charts/releases/tag/kube-prometheus-stack-87.19.2)
[Compare
Source](https://redirect.github.com/prometheus-community/helm-charts/compare/kube-prometheus-stack-87.19.1...kube-prometheus-stack-87.19.2)
kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards,
and Prometheus rules combined with documentation and scripts to provide
easy to operate end-to-end Kubernetes cluster monitoring with Prometheus
using the Prometheus Operator.
#### What's Changed
- \[CI] Update docker/login-action action to v4.5.1 by
[@renovate](https://redirect.github.com/renovate)\[bot] in
[#7134](https://redirect.github.com/prometheus-community/helm-charts/pull/7134)
- \[CI] Update dependency helm-unittest/helm-unittest to v1.1.2 by
[@renovate](https://redirect.github.com/renovate)\[bot] in
[#7135](https://redirect.github.com/prometheus-community/helm-charts/pull/7135)
- \[kube-prometheus-stack] Update Helm release grafana to v12.8.1 by
[@renovate](https://redirect.github.com/renovate)\[bot] in
[#7136](https://redirect.github.com/prometheus-community/helm-charts/pull/7136)
**Full Changelog**:
###
[`v87.19.1`](https://redirect.github.com/prometheus-community/helm-charts/releases/tag/kube-prometheus-stack-87.19.1)
kube-prometheus-stack collects Kubernetes manifests, Grafana dashboards,
and Prometheus rules combined with documentation and scripts to provide
easy to operate end-to-end Kubernetes cluster monitoring with Prometheus
using the Prometheus Operator.
#### What's Changed
- \[kube-prometheus-stack] Update kube-prometheus-stack dependency
non-major updates by
[@renovate](https://redirect.github.com/renovate)\[bot] in
[#7132](https://redirect.github.com/prometheus-community/helm-charts/pull/7132)
**Full Changelog**:
---
### Configuration
π
**Schedule**: (in timezone Europe/Berlin)
- Branch creation
- "after 6pm every weekday,every weekend,before 8am every weekday"
- Automerge
- At any time (no schedule defined)
π¦ **Automerge**: Enabled.
β» **Rebasing**: Whenever PR is behind base branch, or you tick the
rebase/retry checkbox.
π» **Immortal**: This PR will be recreated if closed unmerged. Get
[config
help](https://redirect.github.com/renovatebot/renovate/discussions) if
that's undesired.
---
- [ ] If you want to rebase/retry this PR, check
this box
---
This PR was generated by [Mend Renovate](https://mend.io/renovate/).
View the [repository job
log](https://developer.mend.io/github/cobaltcore-dev/cortex).
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
go.mod | 2 +-
go.sum | 8 ++++----
helm/dev/cortex-prometheus-operator/Chart.yaml | 2 +-
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/go.mod b/go.mod
index 62183ca7a..e5933302a 100644
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,7 @@ require (
github.com/go-gorp/gorp v2.2.0+incompatible
github.com/gophercloud/gophercloud/v2 v2.13.0
github.com/ironcore-dev/ironcore v0.4.3
- github.com/prometheus/client_golang v1.24.0
+ github.com/prometheus/client_golang v1.24.1
github.com/prometheus/client_model v0.6.2
github.com/sapcc/go-bits v0.0.0-20260723170232-89c8670b5841
go.xyrillian.de/gg v1.11.1
diff --git a/go.sum b/go.sum
index 037a803f6..cfd3b3f69 100644
--- a/go.sum
+++ b/go.sum
@@ -143,8 +143,8 @@ github.com/itchyny/timefmt-go v0.1.8 h1:1YEo1JvfXeAHKdjelbYr/uCuhkybaHCeTkH8Bo79
github.com/itchyny/timefmt-go v0.1.8/go.mod h1:5E46Q+zj7vbTgWY8o5YkMeYb4I6GeWLFnetPy5oBrAI=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
-github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ=
-github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
+github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
+github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -191,8 +191,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/poy/onpar v0.3.5 h1:AYOT1AvNtucJhmEK6BSD1KvLvtYXvp/50vL5yaPAljo=
github.com/poy/onpar v0.3.5/go.mod h1:Ae6eC73WNjI7NHdcughszLtcw+msOi0pb6eq6LzL97o=
-github.com/prometheus/client_golang v1.24.0 h1:5XStIklKuAtJSNpdD3s8XJj/Yv78IQmE1kbNk87JrAI=
-github.com/prometheus/client_golang v1.24.0/go.mod h1:QcsNdotprC2nS4BTM2ucbcqxd2CeXTEa9jW7zHO9iDE=
+github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
+github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY=
diff --git a/helm/dev/cortex-prometheus-operator/Chart.yaml b/helm/dev/cortex-prometheus-operator/Chart.yaml
index 862d9378f..406d41f58 100644
--- a/helm/dev/cortex-prometheus-operator/Chart.yaml
+++ b/helm/dev/cortex-prometheus-operator/Chart.yaml
@@ -10,4 +10,4 @@ dependencies:
# CRDs of the prometheus operator, such as PrometheusRule, ServiceMonitor, etc.
- name: kube-prometheus-stack
repository: oci://ghcr.io/prometheus-community/charts
- version: 87.19.0
+ version: 87.19.2
From a881c3c403a70fb6babd92209626509398c3a79c Mon Sep 17 00:00:00 2001
From: juliusclausnitzer
Date: Mon, 27 Jul 2026 10:16:38 +0200
Subject: [PATCH 05/11] fix: stop committed resource controller reconcile storm
(#1089)
setAccepted unconditionally wrote a new AcceptedAt timestamp and a
time-varying StatusSummary on every call, causing a non-empty status
patch even when the CR was already accepted for the current generation.
The self-watch (EnqueueRequestForObject) fired on each patch,
re-enqueuing every accepted cores commitment in a tight ~2s loop and
keeping the workqueue depth permanently elevated around 80.
Add an early-return guard in setAccepted that skips the patch when
Ready=True/Accepted is already set for the current generation.
---------
Signed-off-by: Julius Clausnitzer
---
.../committed_resource_controller.go | 10 ++++
.../committed_resource_controller_test.go | 49 +++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/internal/scheduling/reservations/commitments/committed_resource_controller.go b/internal/scheduling/reservations/commitments/committed_resource_controller.go
index cd0bdc88a..c592bed9c 100644
--- a/internal/scheduling/reservations/commitments/committed_resource_controller.go
+++ b/internal/scheduling/reservations/commitments/committed_resource_controller.go
@@ -396,6 +396,16 @@ func (r *CommittedResourceController) checkChildReservationStatus(ctx context.Co
}
func (r *CommittedResourceController) setAccepted(ctx context.Context, cr *v1alpha1.CommittedResource) error {
+ // Skip the patch when the CR is already accepted for the current generation.
+ // Without this guard, every reconcile writes a new AcceptedAt timestamp and a
+ // time-varying StatusSummary, triggering the self-watch and causing a reconcile storm.
+ cond := meta.FindStatusCondition(cr.Status.Conditions, v1alpha1.CommittedResourceConditionReady)
+ if cond != nil &&
+ cond.Status == metav1.ConditionTrue &&
+ cond.Reason == v1alpha1.CommittedResourceReasonAccepted &&
+ cond.ObservedGeneration == cr.Generation {
+ return nil
+ }
now := metav1.Now()
old := cr.DeepCopy()
specCopy := cr.Spec.DeepCopy()
diff --git a/internal/scheduling/reservations/commitments/committed_resource_controller_test.go b/internal/scheduling/reservations/commitments/committed_resource_controller_test.go
index 5843bb3d9..293f074a9 100644
--- a/internal/scheduling/reservations/commitments/committed_resource_controller_test.go
+++ b/internal/scheduling/reservations/commitments/committed_resource_controller_test.go
@@ -1165,3 +1165,52 @@ func TestCheckChildReservationStatus_GenerationGuard(t *testing.T) {
})
}
}
+
+func TestCommittedResourceController_SetAcceptedIdempotent(t *testing.T) {
+ // Reconciling an already-accepted cores CR must not patch the status again.
+ // Without the idempotency guard, every reconcile writes a new AcceptedAt timestamp,
+ // which triggers the self-watch and causes a reconcile storm.
+ scheme := newCRTestScheme(t)
+ cr := newTestCoresCR("test-cr", v1alpha1.CommitmentStatusConfirmed, 4, false)
+ cr.Generation = 1
+ fgc := newTestFlavorGroupCapacity("test-group", "test-az", 16)
+ k8sClient := newCRTestClient(scheme, cr, fgc)
+
+ controller := &CommittedResourceController{
+ Client: k8sClient,
+ Scheme: scheme,
+ Conf: CommittedResourceControllerConfig{RequeueIntervalRetry: metav1.Duration{Duration: 1 * time.Minute}},
+ }
+
+ // First reconcile: CR transitions to Accepted and status is written.
+ if _, err := controller.Reconcile(context.Background(), reconcileReq(cr.Name)); err != nil {
+ t.Fatalf("first reconcile: %v", err)
+ }
+ assertCondition(t, k8sClient, cr.Name, metav1.ConditionTrue, v1alpha1.CommittedResourceReasonAccepted)
+
+ var after1 v1alpha1.CommittedResource
+ if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: cr.Name}, &after1); err != nil {
+ t.Fatalf("get after first reconcile: %v", err)
+ }
+ cond := meta.FindStatusCondition(after1.Status.Conditions, v1alpha1.CommittedResourceConditionReady)
+ if cond == nil {
+ t.Fatalf("Ready condition not set after first reconcile")
+ }
+ if cond.ObservedGeneration != 1 {
+ t.Errorf("ObservedGeneration: want 1, got %d", cond.ObservedGeneration)
+ }
+ rv1 := after1.ResourceVersion
+
+ // Second reconcile: CR is already accepted β must not patch status.
+ if _, err := controller.Reconcile(context.Background(), reconcileReq(cr.Name)); err != nil {
+ t.Fatalf("second reconcile: %v", err)
+ }
+
+ var after2 v1alpha1.CommittedResource
+ if err := k8sClient.Get(context.Background(), types.NamespacedName{Name: cr.Name}, &after2); err != nil {
+ t.Fatalf("get after second reconcile: %v", err)
+ }
+ if after2.ResourceVersion != rv1 {
+ t.Errorf("ResourceVersion changed on second reconcile (%s β %s): status was patched unnecessarily", rv1, after2.ResourceVersion)
+ }
+}
From 98772a2ffdf6545e378084d0ff7f2abb7a3509dd Mon Sep 17 00:00:00 2001
From: "cortex-ai-agents[bot]"
<279748396+cortex-ai-agents[bot]@users.noreply.github.com>
Date: Mon, 27 Jul 2026 10:17:33 +0200
Subject: [PATCH 06/11] docs: add History CRD documentation and multicluster
guide link (#1091)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Summary
- Add `### History` section to `docs/apis.md` documenting the History
CRD as a scheduling decision audit trail, with relationship to pipelines
noted and added to the mermaid diagram
- Add link to `docs/guides/multicluster/readme.md` from the
documentation landing page
## Test plan
- [ ] Verify markdown renders correctly
- [ ] Confirm History CRD documentation matches actual struct in
`api/v1alpha1/history_types.go`
π€ Generated with [Claude Code](https://claude.com/claude-code)
Assisted-by: Claude Code:claude-opus-4-8 [Bash] [Read] [Edit]
Co-authored-by: cortex-ai-agents[bot] <279748396+cortex-ai-agents[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7
---
docs/apis.md | 12 ++++++++++++
docs/readme.md | 1 +
2 files changed, 13 insertions(+)
diff --git a/docs/apis.md b/docs/apis.md
index f73753d85..a1edf6a14 100644
--- a/docs/apis.md
+++ b/docs/apis.md
@@ -22,9 +22,11 @@ graph LR;
committedresource(CommittedResource CRD)
projectquota(ProjectQuota CRD)
flavorgroupcapacity(FlavorGroupCapacity CRD)
+ history(History CRD)
pipeline --> descheduling
pipeline --> decision
pipeline --> reservation
+ pipeline --> history
committedresource --> reservation
committedresource --> projectquota
flavorgroupcapacity --> committedresource
@@ -104,6 +106,16 @@ Decisions are generated when pipelines are executed with an appropriate request,
In its state, decisions reflect the outcome of the pipeline execution, for example the generated weights for each scheduling step. This outcome is reflected back to the caller of the pipeline. In addition, decisions provide a human-readable explanation why the workload was placed at this specific location.
+### History
+
+```bash
+kubectl get histories
+```
+
+History is a cluster-scoped audit trail of scheduling decisions for a given resource (e.g., a Nova instance). Each time a pipeline produces a placement decision, the result β including which pipeline was used, the scheduling intent, the target host, and an explanation β is recorded unless the caller sets `SkipHistory=true` in the pipeline options. The most recent decision lives in `status.current`; older entries are compacted into `status.history`, capped at 10 entries.
+
+See [`api/v1alpha1/history_types.go`](../api/v1alpha1/history_types.go) for the full struct definition.
+
### Reservations
```bash
diff --git a/docs/readme.md b/docs/readme.md
index 4d9c28cb8..ec994f075 100644
--- a/docs/readme.md
+++ b/docs/readme.md
@@ -7,3 +7,4 @@
- To get started quickly, see [the quickstart guide](quickstart.md).
- For details on committed resource reservations, see [committed resource reservations](reservations/committed-resource-reservations.md).
- For details on failover reservations, see [failover reservations](reservations/failover-reservations.md).
+- For multi-cluster scheduling, see [the multicluster guide](guides/multicluster/readme.md).
From 4a472c5f96759e94aced15b99ac413869e003974 Mon Sep 17 00:00:00 2001
From: "cortex-ai-agents[bot]"
<279748396+cortex-ai-agents[bot]@users.noreply.github.com>
Date: Mon, 27 Jul 2026 10:18:29 +0200
Subject: [PATCH 07/11] fix: reset gauge metrics in reservation monitor to
prevent stale values (#1092)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Summary
- Add `Reset()` calls on `numberOfReservations` and `reservedResources`
GaugeVecs before repopulating in `Collect`, preventing stale label
combinations from persisting when reservations are deleted or change
status
- Add context timeout on the Kubernetes List call to prevent scrape
hangs
- Follows the same pattern already used in
`internal/scheduling/reservations/capacity/metrics.go`
## Test plan
- [ ] Verify `make test` passes
- [ ] Verify `make lint` passes
- [ ] Compare with the capacity/metrics.go pattern to confirm
consistency
π€ Generated with [Claude Code](https://claude.com/claude-code)
Assisted-by: Claude Code:claude-opus-4-8 [Bash] [Read] [Edit]
Co-authored-by: cortex-ai-agents[bot] <279748396+cortex-ai-agents[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7
---
internal/scheduling/reservations/monitor.go | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/internal/scheduling/reservations/monitor.go b/internal/scheduling/reservations/monitor.go
index 557a87920..6cefa301b 100644
--- a/internal/scheduling/reservations/monitor.go
+++ b/internal/scheduling/reservations/monitor.go
@@ -6,6 +6,7 @@ package reservations
import (
"context"
"strings"
+ "time"
"github.com/cobaltcore-dev/cortex/api/v1alpha1"
"github.com/prometheus/client_golang/prometheus"
@@ -53,14 +54,20 @@ func (m *Monitor) Describe(ch chan<- *prometheus.Desc) {
func (m *Monitor) Collect(ch chan<- prometheus.Metric) {
// Fetch all reservations from kubernetes.
var reservations v1alpha1.ReservationList
+ ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
+ defer cancel()
if err := m.List(
- context.Background(),
+ ctx,
&reservations,
); err != nil {
monitorLog.Error(err, "failed to list reservations")
return
}
+ // Reset all gauges so deleted reservations don't linger.
+ m.numberOfReservations.Reset()
+ m.reservedResources.Reset()
+
countByLabels := map[string]uint64{}
for _, reservation := range reservations.Items {
readyCondition := meta.FindStatusCondition(reservation.Status.Conditions, v1alpha1.ReservationConditionReady)
From 4f44f3b7c2d52738bf46b70e530ee58eea70596a Mon Sep 17 00:00:00 2001
From: "cortex-ai-agents[bot]"
<279748396+cortex-ai-agents[bot]@users.noreply.github.com>
Date: Mon, 27 Jul 2026 13:49:03 +0200
Subject: [PATCH 08/11] fix: deep-copy capacity map to prevent informer cache
corruption (#1065)
The capacity filter assigned hypervisor Status.Capacity map references
directly into a local working map, then mutated those maps during
free-resource calculations. Since the maps are shared with the
controller-runtime informer cache, each scheduling pass permanently
decremented cached capacity values, progressively starving scheduling
until all hosts appeared full.
Fix: deep-copy the capacity map per hypervisor before subtracting
allocations so the informer cache is never mutated.
Assisted-by: Claude Code:claude-opus-4-8 [Bash] [Read] [Edit]
Co-authored-by: cortex-ai-agents[bot] <279748396+cortex-ai-agents[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.7
---
.../plugins/filters/filter_has_enough_capacity.go | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go b/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go
index e2fadf981..117b032ae 100644
--- a/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go
+++ b/internal/scheduling/nova/plugins/filters/filter_has_enough_capacity.go
@@ -82,13 +82,20 @@ func (s *FilterHasEnoughCapacity) Run(traceLog *slog.Logger, request api.Externa
return nil, err
}
for _, hv := range hvs.Items {
+ var sourceMap map[hv1.ResourceName]resource.Quantity
if hv.Status.EffectiveCapacity == nil {
traceLog.Warn("hypervisor with nil effective capacity, use capacity instead (overprovisioning not considered)", "host", hv.Name)
- freeResourcesByHost[hv.Name] = hv.Status.Capacity
+ sourceMap = hv.Status.Capacity
} else {
// Start with the total effective capacity which is capacity * overcommit ratio.
- freeResourcesByHost[hv.Name] = hv.Status.EffectiveCapacity
+ sourceMap = hv.Status.EffectiveCapacity
}
+ // Deep-copy the map to avoid mutating the informer cache.
+ copied := make(map[hv1.ResourceName]resource.Quantity, len(sourceMap))
+ for k, v := range sourceMap {
+ copied[k] = v.DeepCopy()
+ }
+ freeResourcesByHost[hv.Name] = copied
// Subtract allocated resources (skip when ignoring allocations for empty-datacenter capacity queries).
if !ignoreAllocations {
From f2e1762897fe18c50bd0863603f58ca2d0087970 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 27 Jul 2026 14:21:30 +0200
Subject: [PATCH 09/11] bump app version [skip ci] (#1084)
bump app version [skip ci]
```
bumped cortex: sha-38f37225 -> sha-4f44f3b7
bumped cortex-shim: sha-38f37225 -> sha-51c773d9
noop cortex-postgres (sha-e06153f8)
```
Signed-off-by: juliusclausnitzer <65490082+juliusclausnitzer@users.noreply.github.com>
Co-authored-by: juliusclausnitzer <65490082+juliusclausnitzer@users.noreply.github.com>
---
helm/library/cortex-shim/Chart.yaml | 2 +-
helm/library/cortex/Chart.yaml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/helm/library/cortex-shim/Chart.yaml b/helm/library/cortex-shim/Chart.yaml
index 51f77277f..9fd548540 100644
--- a/helm/library/cortex-shim/Chart.yaml
+++ b/helm/library/cortex-shim/Chart.yaml
@@ -3,6 +3,6 @@ name: cortex-shim
description: A Helm chart to distribute cortex shims.
type: application
version: 0.1.9
-appVersion: "sha-38f37225"
+appVersion: "sha-51c773d9"
icon: "https://example.com/icon.png"
dependencies: []
diff --git a/helm/library/cortex/Chart.yaml b/helm/library/cortex/Chart.yaml
index 579d7d35a..23f7ad87c 100644
--- a/helm/library/cortex/Chart.yaml
+++ b/helm/library/cortex/Chart.yaml
@@ -3,6 +3,6 @@ name: cortex
description: A Helm chart to distribute cortex.
type: application
version: 0.3.3
-appVersion: "sha-38f37225"
+appVersion: "sha-4f44f3b7"
icon: "https://example.com/icon.png"
dependencies: []
From 68212b99f095715efbe0739a2c543cd1e77a07a0 Mon Sep 17 00:00:00 2001
From: "cortex-ai-agents[bot]"
<279748396+cortex-ai-agents[bot]@users.noreply.github.com>
Date: Mon, 27 Jul 2026 15:08:32 +0200
Subject: [PATCH 10/11] Release cortex 0.3.4 (#1094)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
## Summary
- Adds changelog entry for cortex v0.3.4
- Bumps helm chart versions across all bundles and library charts
- Release prep for #1093: merge this before merging #1093
## Test plan
- [ ] Verify changelog entry is correct and complete
- [ ] Verify helm chart version bumps are consistent across all charts
- [ ] CI passes
π€ Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: cortex-ai-agents[bot] <279748396+cortex-ai-agents[bot]@users.noreply.github.com>
Co-authored-by: juliusclausnitzer
Co-authored-by: Claude Opus 4.7
---
CHANGELOG.md | 48 +++++++++++++++++++
helm/bundles/cortex-cinder/Chart.yaml | 6 +--
helm/bundles/cortex-crds/Chart.yaml | 4 +-
helm/bundles/cortex-ironcore/Chart.yaml | 4 +-
helm/bundles/cortex-manila/Chart.yaml | 6 +--
helm/bundles/cortex-nova/Chart.yaml | 6 +--
helm/bundles/cortex-placement-shim/Chart.yaml | 4 +-
helm/bundles/cortex-pods/Chart.yaml | 4 +-
helm/library/cortex-shim/Chart.yaml | 2 +-
helm/library/cortex/Chart.yaml | 2 +-
10 files changed, 67 insertions(+), 19 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 60edd20e6..24ab3d98c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,53 @@
# Changelog
+## 2026-07-27 β [#1093](https://github.com/cobaltcore-dev/cortex/pull/1093)
+
+### cortex v0.3.4 (sha-4f44f3b7)
+
+Bug fixes:
+- Deep-copy capacity map to prevent informer cache corruption β the capacity filter assigned hypervisor Status.Capacity map references directly into a local working map, then mutated those maps during free-resource calculations. Since the maps are shared with the controller-runtime informer cache, each scheduling pass permanently decremented cached capacity values, progressively starving scheduling until all hosts appeared full ([#1065](https://github.com/cobaltcore-dev/cortex/pull/1065))
+- Reset gauge metrics in reservation monitor to prevent stale values β adds `Reset()` calls on `numberOfReservations` and `reservedResources` GaugeVecs before repopulating in `Collect`, preventing stale label combinations from persisting when reservations are deleted or change status ([#1092](https://github.com/cobaltcore-dev/cortex/pull/1092))
+- Stop committed resource controller reconcile storm β `setAccepted` unconditionally wrote a new AcceptedAt timestamp and a time-varying StatusSummary on every call, causing a non-empty status patch even when the CR was already accepted. Adds an early-return guard that skips the patch when Ready=True/Accepted is already set for the current generation ([#1089](https://github.com/cobaltcore-dev/cortex/pull/1089))
+
+Non-breaking changes:
+- Add History CRD documentation and multicluster guide link ([#1091](https://github.com/cobaltcore-dev/cortex/pull/1091))
+- Update `github.com/prometheus/client_golang` to v1.24.1 ([#1090](https://github.com/cobaltcore-dev/cortex/pull/1090))
+- Update `k8s.io/api`, `k8s.io/apimachinery`, `k8s.io/client-go` to v0.36.3 ([#1086](https://github.com/cobaltcore-dev/cortex/pull/1086))
+- Update `github.com/sapcc/go-bits` ([#1085](https://github.com/cobaltcore-dev/cortex/pull/1085))
+- Update `kube-prometheus-stack` to 87.19.2 ([#1090](https://github.com/cobaltcore-dev/cortex/pull/1090))
+
+### cortex-shim v0.1.10 (sha-51c773d9)
+
+Includes updated image sha-51c773d9 with dependency updates.
+
+### cortex-nova v0.0.84
+
+Includes updated chart cortex v0.3.4.
+
+### cortex-cinder v0.0.84
+
+Includes updated chart cortex v0.3.4.
+
+### cortex-manila v0.0.84
+
+Includes updated chart cortex v0.3.4.
+
+### cortex-crds v0.0.84
+
+Includes updated chart cortex v0.3.4.
+
+### cortex-ironcore v0.0.84
+
+Includes updated chart cortex v0.3.4.
+
+### cortex-pods v0.0.84
+
+Includes updated chart cortex v0.3.4.
+
+### cortex-placement-shim v0.1.10
+
+Includes updated chart cortex-shim v0.1.10.
+
## 2026-07-23 β [#1080](https://github.com/cobaltcore-dev/cortex/pull/1080)
### cortex v0.3.3 (sha-4eba8400)
diff --git a/helm/bundles/cortex-cinder/Chart.yaml b/helm/bundles/cortex-cinder/Chart.yaml
index 2aa7b027f..17845a1a4 100644
--- a/helm/bundles/cortex-cinder/Chart.yaml
+++ b/helm/bundles/cortex-cinder/Chart.yaml
@@ -5,7 +5,7 @@ apiVersion: v2
name: cortex-cinder
description: A Helm chart deploying Cortex for Cinder.
type: application
-version: 0.0.83
+version: 0.0.84
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex-postgres
@@ -16,12 +16,12 @@ dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
alias: cortex-knowledge-controllers
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
alias: cortex-scheduling-controllers
# Owner info adds a configmap to the kubernetes cluster with information on
diff --git a/helm/bundles/cortex-crds/Chart.yaml b/helm/bundles/cortex-crds/Chart.yaml
index 7c3cadeab..4334a9fb2 100644
--- a/helm/bundles/cortex-crds/Chart.yaml
+++ b/helm/bundles/cortex-crds/Chart.yaml
@@ -5,13 +5,13 @@ apiVersion: v2
name: cortex-crds
description: A Helm chart deploying Cortex CRDs.
type: application
-version: 0.0.83
+version: 0.0.84
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
# Owner info adds a configmap to the kubernetes cluster with information on
# the service owner. This makes it easier to find out who to contact in case
diff --git a/helm/bundles/cortex-ironcore/Chart.yaml b/helm/bundles/cortex-ironcore/Chart.yaml
index 7ce01100e..308a117dc 100644
--- a/helm/bundles/cortex-ironcore/Chart.yaml
+++ b/helm/bundles/cortex-ironcore/Chart.yaml
@@ -5,13 +5,13 @@ apiVersion: v2
name: cortex-ironcore
description: A Helm chart deploying Cortex for IronCore.
type: application
-version: 0.0.83
+version: 0.0.84
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
# Owner info adds a configmap to the kubernetes cluster with information on
# the service owner. This makes it easier to find out who to contact in case
diff --git a/helm/bundles/cortex-manila/Chart.yaml b/helm/bundles/cortex-manila/Chart.yaml
index 146cc82ae..6200dfbbb 100644
--- a/helm/bundles/cortex-manila/Chart.yaml
+++ b/helm/bundles/cortex-manila/Chart.yaml
@@ -5,7 +5,7 @@ apiVersion: v2
name: cortex-manila
description: A Helm chart deploying Cortex for Manila.
type: application
-version: 0.0.83
+version: 0.0.84
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex-postgres
@@ -16,12 +16,12 @@ dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
alias: cortex-knowledge-controllers
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
alias: cortex-scheduling-controllers
# Owner info adds a configmap to the kubernetes cluster with information on
diff --git a/helm/bundles/cortex-nova/Chart.yaml b/helm/bundles/cortex-nova/Chart.yaml
index 832cd56c1..8178bc34e 100644
--- a/helm/bundles/cortex-nova/Chart.yaml
+++ b/helm/bundles/cortex-nova/Chart.yaml
@@ -5,7 +5,7 @@ apiVersion: v2
name: cortex-nova
description: A Helm chart deploying Cortex for Nova.
type: application
-version: 0.0.83
+version: 0.0.84
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex-postgres
@@ -16,12 +16,12 @@ dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
alias: cortex-knowledge-controllers
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
alias: cortex-scheduling-controllers
# Owner info adds a configmap to the kubernetes cluster with information on
diff --git a/helm/bundles/cortex-placement-shim/Chart.yaml b/helm/bundles/cortex-placement-shim/Chart.yaml
index d58bb6054..5f45c887f 100644
--- a/helm/bundles/cortex-placement-shim/Chart.yaml
+++ b/helm/bundles/cortex-placement-shim/Chart.yaml
@@ -5,13 +5,13 @@ apiVersion: v2
name: cortex-placement-shim
description: A Helm chart deploying the Cortex placement shim.
type: application
-version: 0.1.9
+version: 0.1.10
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex-shim
- name: cortex-shim
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.1.9
+ version: 0.1.10
# Owner info adds a configmap to the kubernetes cluster with information on
# the service owner. This makes it easier to find out who to contact in case
# of issues. See: https://github.com/sapcc/helm-charts/pkgs/container/helm-charts%2Fowner-info
diff --git a/helm/bundles/cortex-pods/Chart.yaml b/helm/bundles/cortex-pods/Chart.yaml
index a08c74900..4cc50ed57 100644
--- a/helm/bundles/cortex-pods/Chart.yaml
+++ b/helm/bundles/cortex-pods/Chart.yaml
@@ -5,13 +5,13 @@ apiVersion: v2
name: cortex-pods
description: A Helm chart deploying Cortex for Pods.
type: application
-version: 0.0.83
+version: 0.0.84
appVersion: 0.1.0
dependencies:
# from: file://../../library/cortex
- name: cortex
repository: oci://ghcr.io/cobaltcore-dev/cortex/charts
- version: 0.3.3
+ version: 0.3.4
# Owner info adds a configmap to the kubernetes cluster with information on
# the service owner. This makes it easier to find out who to contact in case
diff --git a/helm/library/cortex-shim/Chart.yaml b/helm/library/cortex-shim/Chart.yaml
index 9fd548540..9d88a4841 100644
--- a/helm/library/cortex-shim/Chart.yaml
+++ b/helm/library/cortex-shim/Chart.yaml
@@ -2,7 +2,7 @@ apiVersion: v2
name: cortex-shim
description: A Helm chart to distribute cortex shims.
type: application
-version: 0.1.9
+version: 0.1.10
appVersion: "sha-51c773d9"
icon: "https://example.com/icon.png"
dependencies: []
diff --git a/helm/library/cortex/Chart.yaml b/helm/library/cortex/Chart.yaml
index 23f7ad87c..a1434b7e5 100644
--- a/helm/library/cortex/Chart.yaml
+++ b/helm/library/cortex/Chart.yaml
@@ -2,7 +2,7 @@ apiVersion: v2
name: cortex
description: A Helm chart to distribute cortex.
type: application
-version: 0.3.3
+version: 0.3.4
appVersion: "sha-4f44f3b7"
icon: "https://example.com/icon.png"
dependencies: []
From 1ae9669c58735bd6d85f3e73604c20ae8bd528b0 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Mon, 27 Jul 2026 15:42:12 +0200
Subject: [PATCH 11/11] bump app version [skip ci] (#1095)
bump app version [skip ci]
```
bumped cortex: sha-4f44f3b7 -> sha-68212b99
noop cortex-shim (sha-51c773d9)
noop cortex-postgres (sha-e06153f8)
```
Signed-off-by: juliusclausnitzer <65490082+juliusclausnitzer@users.noreply.github.com>
Co-authored-by: juliusclausnitzer <65490082+juliusclausnitzer@users.noreply.github.com>
---
helm/library/cortex/Chart.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/helm/library/cortex/Chart.yaml b/helm/library/cortex/Chart.yaml
index a1434b7e5..7049941b9 100644
--- a/helm/library/cortex/Chart.yaml
+++ b/helm/library/cortex/Chart.yaml
@@ -3,6 +3,6 @@ name: cortex
description: A Helm chart to distribute cortex.
type: application
version: 0.3.4
-appVersion: "sha-4f44f3b7"
+appVersion: "sha-68212b99"
icon: "https://example.com/icon.png"
dependencies: []