Repository: kubernetes-sigs/kueue

Issue:
TAS: support balanced placement

**What would you like to be added**:

The new option aside from BestFit for balanced placement which tries to "balance" the split for the number of Pods between a pair of domains. 

For example, assume we have a Job with 16 Pods which cannot all fit into a single rack, but two.

We found experimentally that the split 8:8 into racks performs better than 1:15.

Some open questions which would be good to clarify:
- what to do if perfect split is not possible, for example, should we go with 9:7 or 10:6?
- is 3 racks "balanced"  6:6:4 better than two skewed 15:1?
- what to do about 2-level scheduling, should we balance at the level of Pods or PodSlices?

We can already start prototyping to guide some of the decisions to see what is easily available and assessing the gain  / effort ration.

However, I expect a KEP update with the finalized proposal regarding the open-questions. 

We can introduce the new policy behind an Alpha feature gate to collect feedback.

**Why is this needed**:

To optimize performance by balancing the counts of Pods when possible.

Hints from issue comments:
@mimowo: cc @mwysokin @tenzen-y @PBundyra @tenzen-y: Basically, LGTM. Actually, I requested a similar profile, previously, for Inference workloads.
What is the key difference from the previous TASProfileLeastFreeCapacity profile?

@mwysokin: @tenzen-y The main motivation is to provide great default experience for GB200. According to our internal research the difference in performance is really significant based on whether compact placement (BestFit) or some kind of Balanced/Symmetrical placement is used. Some NCCL primitives seem to be really sensitive to how many host network interfaces are available in multi-NVL72 setups and cross-rack traffic. This of course comes at a price of cluster fragmentation that's why we should probably start with the feature hidden behind a feature flag and if we see some positive feedback we could maybe allow to configure placement policies at the topology level to support heterogenous clusters. I can imagine that future hardware architectures are going to be more and more convoluted. WDYT?

For the required topology request this is probably not needed since an expert AI engineer who's using the required mode should do some kind of direct mapping of PodSlices/WorkerGroups to NVL72 domains. But for preferred and unconstrained (implicit) this would provide great default experience.

Some examples of what we currently think this should behave like:

```py
  # balanced placement pseudo function accepts a list of blocks with racks with available GPUs as values of each block list
  >>> balanced_placement(blocks=[[18, 18]], requested_gpu_blocks=20)
  [[10, 10]]
  >>> balanced_placement(blocks=[[18, 2]], requested_gpu_blocks=20)
  [[18, 2]]
  >>> balanced_placement(blocks=[[18, 18], [18, 18, 18], [18]], requested_gpu_blocks=54)
  [[0, 0], [18, 18, 18], [0]]
  >>> balanced_placement(blocks=[[18, 15, 10]], requested_gpu_blocks=25)
  [[0, 15, 10]]
```@tenzen-y: > [@tenzen-y](https://github.com/tenzen-y) The main motivation is to provide great default experience for GB200. According to our internal research the difference in performance is really significant based on whether compact placement (BestFit) or some kind of Balanced/Symmetrical placement is used. Some NCCL primitives are really sensitive to how many host network interfaces are available and . This of course come at a price of cluster fragmentation that's why we should probably start with the feature hidden behind a feature flag and if we see some positive feedback we could maybe allow to configure placement policies at the topology level to support heterogenous clusters. I can imagine that future hardware architectures are going to be more and more convoluted. WDYT?


@mwysokin Thank you for sharing an interesting performance problem for GB200. I didn't know that the GB200 interconnect architecture does not have full bisection bandwidth. Does that mean GB200 has oversubsdcibed bandwidth, right?
Anyway, I'm fine with introducing new TAS profile and FG to enable / disable the profile across cluster-wise, first.

> > For the required topology request this is probably not needed since an expert AI engineer who's using the required mode should do some kind of direct mapping of PodSlices/WorkerGroups to NVL72 domains. But for preferred and unconstrained (implicit) this would provide great default experience.

That makes sense. Let's consider that as another feature request. I think we could consider that as a finegrained Topology Assignment Algorithm per Workload as opposed to the current cluster-wide one.@mwysokin: > [@mwysokin](https://github.com/mwysokin) Thank you for sharing an interesting performance problem for GB200. I didn't know that the GB200 interconnect architecture does not have full bisection bandwidth. Does that mean GB200 has oversubsdcibed bandwidth, right? Anyway, I'm fine with introducing new TAS profile and FG to enable / disable the profile across cluster-wise, first.

Sounds great. I don't know full technical details behind this behavior. But we've seen it in our internal benchmarks.
Maybe @klueska could shed some light on it. I think he's involved in GB200 and DRA work.

> 
> > > For the required topology request this is probably not needed since an expert AI engineer who's using the required mode should do some kind of direct mapping of PodSlices/WorkerGroups to NVL72 domains. But for preferred and unconstrained (implicit) this would provide great default experience.
> 
> That makes sense. Let's consider that as another feature request. I think we could consider that as a finegrained Topology Assignment Algorithm per Workload as opposed to the current cluster-wide one.

SGTM 🖖 @YamasouA: Hello, I'd like to work on this feature.

@mimowo @tenzen-y @mwysokin 
Can I discuss it here and start implementation? or need KEP?
I have no experience of KEP, so, I may not be the right person for this, if we need KEP. (Of course, I'd like to challenge, if it is OK.)

/assign@mwysokin: So in order not to duplicate the effort AFAIK @pajakd is already working on it. I'm not sure why he's not assigned to the task. Maybe both of you could figure out how to divide the scope of this task and work on it together?

There're also multiple follow-ups to this particular task ready to be grabbed like extending the API with configurable placement and refactoring the code to even allow configurable placement in the first place. I think at the moment we have a bit of spaghetti with multiple branches in the same function depending on the placement policy used and it'd be awesome if we could untangle it. The first one though requires updates to the KEP.

Or we could compare both solutions  and potentially take best parts from both but I'm not sure if you'd be interested in that.@tenzen-y: > Hello, I'd like to work on this feature.
> 
> [@mimowo](https://github.com/mimowo) [@tenzen-y](https://github.com/tenzen-y) [@mwysokin](https://github.com/mwysokin) Can I discuss it here and start implementation? or need KEP? I have no experience of KEP, so, I may not be the right person for this, if we need KEP. (Of course, I'd like to challenge, if it is OK.)
> 
> /assign

@YamasouA Thank you for your interest in this issue. This issue requires much deeper Kueue knowledge based on code. So, this might not match for the first-time contributor. I would like to offer to start with a non-difficult issue.
@pajakd: Hi as @mwysokin wrote. I already started some work on this (sorry for not assigning myself to it). I hope it is fine @YamasouA 

I'm happy to share the task but I would like to provide the first implementation of the balanced placement algorithm.

/assign@tenzen-y: > Hi as [@mwysokin](https://github.com/mwysokin) wrote. I already started some work on this (sorry for not assigning myself to it). I hope it is fine [@YamasouA](https://github.com/YamasouA)
> 
> I'm happy to share the task but I would like to provide the first implementation of the balanced placement algorithm.
> 
> /assign

@pajakd Could you update KEP as well?@YamasouA: Please let me know if there is anything I can help with.

/unassign

Solution patch:
diff --git a/.golangci-kal.yml b/.golangci-kal.yml
index 344621545..5f356aaff 100644
--- a/.golangci-kal.yml
+++ b/.golangci-kal.yml
@@ -68,6 +68,43 @@ linters:
       linters:
         - kubeapilinter
 
+    ## Exclusions for intentional API design decisions
+    # PodSets field intentionally excludes omitempty
+    - text: "optionalfields: field PodSets should have the omitempty tag."
+      path: "apis/kueue/v1beta2"
+
+    # Spec and Status fields - Kubernetes convention (not pointers, specific omitempty rules)
+    - text: "optionalfields: field (Spec|Status) should (be a pointer|have the omitempty tag)."
+      path: "apis/kueue/v1beta2"
+
+    # Various optional fields intentionally not pointers for API stability
+    - text: "optionalfields: field (QueueName|PriorityClassName|PriorityClassSource|ClusterQueue|ParentName|CohortName|QueueingStrategy|LocationType|Description|Policy|WhenCanBorrow|WhenCanPreempt|ReclaimWithinCohort|WithinClusterQueue|Borrowed|Total|PendingWorkloads|ReservingWorkloads|AdmittedWorkloads) should (be a pointer|have the omitempty tag)."
+      path: "apis/kueue/v1beta2"
+
+    # Name and Count fields - intentional design decisions
+    - text: "(optionalfields|requiredfields): field (Name|Count) should (be a pointer|have the omitempty tag)."
+      path: "apis/kueue/v1beta2"
+
+    # PodSetAssignments intentionally excludes omitempty
+    - text: "optionalfields: field PodSetAssignments should have the omitempty tag."
+      path: "apis/kueue/v1beta2"
+
+    # Required fields with valid zero values - validation is intentionally incomplete
+    - text: "requiredfields: field .* has a valid zero value.*should be a pointer"
+      path: "apis/kueue/v1beta2"
+
+    # Required fields that intentionally exclude omitempty
+    - text: "requiredfields: field (ControllerName|LastUpdate|Reason|UnderlyingCause|Message|WeightedShare|Value|ConsumedResources) should have the omitempty tag."
+      path: "apis/kueue/v1beta2"
+
+    # ResourceList fields (map types required for Kubernetes compatibility)
+    - text: "(nomaps|optionalfields): (field )?(ResourceUsage|Resources|ConsumedResources) should (not use a map type|be a pointer)"
+      path: "apis/kueue/v1beta2"
+
+    # Bool fields for API compatibility (Active mirrors Job.Suspend, Unconstrained is existing API)
+    - text: "(nobools|optionalorrequired): field (Active|Unconstrained) .*(should not use a bool|must be marked as optional or required)"
+      path: "apis/kueue/v1beta2"
+
 issues:
   max-same-issues: 0
   max-issues-per-linter: 0
diff --git a/Makefile-test.mk b/Makefile-test.mk
index d2ec63586..8ef254289 100644
--- a/Makefile-test.mk
+++ b/Makefile-test.mk
@@ -38,7 +38,7 @@ INTEGRATION_OUTPUT_OPTIONS ?= --output-interceptor-mode=none
 
 # Folder where the e2e tests are located.
 E2E_TARGET ?= ./test/e2e/...
-E2E_K8S_VERSIONS ?= 1.31.12 1.32.8 1.33.4 1.34.0
+E2E_K8S_VERSIONS ?= 1.32.8 1.33.4 1.34.0
 E2E_K8S_VERSION ?= 1.34
 E2E_K8S_FULL_VERSION ?= $(filter $(E2E_K8S_VERSION).%,$(E2E_K8S_VERSIONS))
 # Default to E2E_K8S_VERSION.0 if no match is found
diff --git a/README.md b/README.md
index 1e8aa80d9..c62647f2e 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,6 @@ Read the [overview](https://kueue.sigs.k8s.io/docs/overview/) and watch the Kueu
   - ✔️ Integration Test [testgrid](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-integration-main)
   - ✔️ Integration MultiKueue Tests [testgrid](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-integration-multikueue-main)
   - ✔️ E2E Tests for Kubernetes
-    [1.31](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-e2e-main-1-31),
     [1.32](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-e2e-main-1-32),
     [1.33](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-e2e-main-1-33),
     [1.34](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-e2e-main-1-34),
diff --git a/apis/kueue/v1beta1/clusterqueue_conversion.go b/apis/kueue/v1beta1/clusterqueue_conversion.go
index 999355869..6af66ab35 100644
--- a/apis/kueue/v1beta1/clusterqueue_conversion.go
+++ b/apis/kueue/v1beta1/clusterqueue_conversion.go
@@ -39,7 +39,14 @@ func (dst *ClusterQueue) ConvertFrom(srcRaw conversion.Hub) error {
 func Convert_v1beta1_ClusterQueueSpec_To_v1beta2_ClusterQueueSpec(in *ClusterQueueSpec, out *v1beta2.ClusterQueueSpec, s conversionapi.Scope) error {
 	out.CohortName = v1beta2.CohortReference(in.Cohort)
 
-	// Convert AdmissionChecks to AdmissionChecksStrategy before autoConvert
+	// Run autoConvert first to populate out.FlavorFungibility.
+	// We need out.FlavorFungibility to be non-nil before we can update its fields.
+	if err := autoConvert_v1beta1_ClusterQueueSpec_To_v1beta2_ClusterQueueSpec(in, out, s); err != nil {
+		return err
+	}
+
+	// Convert AdmissionChecks to AdmissionChecksStrategy after autoConvert.
+	// This must happen after autoConvert to avoid being overwritten.
 	if len(in.AdmissionChecks) > 0 {
 		out.AdmissionChecksStrategy = &v1beta2.AdmissionChecksStrategy{
 			AdmissionChecks: make([]v1beta2.AdmissionCheckStrategyRule, len(in.AdmissionChecks)),
@@ -51,6 +58,10 @@ func Convert_v1beta1_ClusterQueueSpec_To_v1beta2_ClusterQueueSpec(in *ClusterQue
 		}
 	}
 
+	// Convert deprecated FlavorFungibility values to their v1beta2 equivalents.
+	// This must happen after autoConvert, which creates out.FlavorFungibility.
+	// Preempt -> MayStopSearch
+	// Borrow -> MayStopSearch
 	if in.FlavorFungibility != nil && out.FlavorFungibility != nil {
 		if in.FlavorFungibility.WhenCanPreempt == Preempt {
 			out.FlavorFungibility.WhenCanPreempt = v1beta2.MayStopSearch
@@ -60,7 +71,7 @@ func Convert_v1beta1_ClusterQueueSpec_To_v1beta2_ClusterQueueSpec(in *ClusterQue
 		}
 	}
 
-	return autoConvert_v1beta1_ClusterQueueSpec_To_v1beta2_ClusterQueueSpec(in, out, s)
+	return nil
 }
 
 func Convert_v1beta2_ClusterQueueSpec_To_v1beta1_ClusterQueueSpec(in *v1beta2.ClusterQueueSpec, out *ClusterQueueSpec, s conversionapi.Scope) error {
diff --git a/apis/kueue/v1beta1/clusterqueue_types.go b/apis/kueue/v1beta1/clusterqueue_types.go
index 8a5e9975b..71e48be86 100644
--- a/apis/kueue/v1beta1/clusterqueue_types.go
+++ b/apis/kueue/v1beta1/clusterqueue_types.go
@@ -31,7 +31,6 @@ const (
 	ClusterQueueActiveReasonAdmissionCheckInactive                   = "AdmissionCheckInactive"
 	ClusterQueueActiveReasonMultipleMultiKueueAdmissionChecks        = "MultipleMultiKueueAdmissionChecks"
 	ClusterQueueActiveReasonMultiKueueAdmissionCheckAppliedPerFlavor = "MultiKueueAdmissionCheckAppliedPerFlavor"
-	ClusterQueueActiveReasonNotSupportedWithTopologyAwareScheduling  = "NotSupportedWithTopologyAwareScheduling"
 	ClusterQueueActiveReasonTopologyNotFound                         = "TopologyNotFound"
 	ClusterQueueActiveReasonUnknown                                  = "Unknown"
 	ClusterQueueActiveReasonReady                                    = "Ready"
diff --git a/apis/kueue/v1beta1/workload_conversion.go b/apis/kueue/v1beta1/workload_conversion.go
index 55d407ec5..729b7f863 100644
--- a/apis/kueue/v1beta1/workload_conversion.go
+++ b/apis/kueue/v1beta1/workload_conversion.go
@@ -45,3 +45,27 @@ func Convert_v1beta1_WorkloadStatus_To_v1beta2_WorkloadStatus(in *WorkloadStatus
 	out.AccumulatedPastExecutionTimeSeconds = in.AccumulatedPastExexcutionTimeSeconds
 	return autoConvert_v1beta1_WorkloadStatus_To_v1beta2_WorkloadStatus(in, out, s)
 }
+
+func Convert_v1beta1_WorkloadSpec_To_v1beta2_WorkloadSpec(in *WorkloadSpec, out *v1beta2.WorkloadSpec, s conversionapi.Scope) error {
+	switch in.PriorityClassSource {
+	case WorkloadPriorityClassSource:
+		out.PriorityClassRef = v1beta2.NewWorkloadPriorityClassRef(in.PriorityClassName)
+	case PodPriorityClassSource:
+		out.PriorityClassRef = v1beta2.NewPodPriorityClassRef(in.PriorityClassName)
+	}
+	return autoConvert_v1beta1_WorkloadSpec_To_v1beta2_WorkloadSpec(in, out, s)
+}
+
+func Convert_v1beta2_WorkloadSpec_To_v1beta1_WorkloadSpec(in *v1beta2.WorkloadSpec, out *WorkloadSpec, s conversionapi.Scope) error {
+	if in.PriorityClassRef != nil {
+		switch {
+		case in.PriorityClassRef.Group == v1beta2.WorkloadPriorityClassGroup && in.PriorityClassRef.Kind == v1beta2.WorkloadPriorityClassKind:
+			out.PriorityClassSource = WorkloadPriorityClassSource
+			out.PriorityClassName = in.PriorityClassRef.Name
+		case in.PriorityClassRef.Group == v1beta2.PodPriorityClassGroup && in.PriorityClassRef.Kind == v1beta2.PodPriorityClassKind:
+			out.PriorityClassSource = PodPriorityClassSource
+			out.PriorityClassName = in.PriorityClassRef.Name
+		}
+	}
+	return autoConvert_v1beta2_WorkloadSpec_To_v1beta1_WorkloadSpec(in, out, s)
+}
diff --git a/apis/kueue/v1beta1/workload_types.go b/apis/kueue/v1beta1/workload_types.go
index 1c1d44696..86ab44baa 100644
--- a/apis/kueue/v1beta1/workload_types.go
+++ b/apis/kueue/v1beta1/workload_types.go
@@ -23,6 +23,11 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 )
 
+const (
+	WorkloadPriorityClassSource = "kueue.x-k8s.io/workloadpriorityclass"
+	PodPriorityClassSource      = "scheduling.k8s.io/priorityclass"
+)
+
 // WorkloadSpec defines the desired state of Workload
 // +kubebuilder:validation:XValidation:rule="has(self.priorityClassName) ? has(self.priority) : true", message="priority should not be nil when priorityClassName is set"
 type WorkloadSpec struct {
diff --git a/apis/kueue/v1beta1/zz_generated.conversion.go b/apis/kueue/v1beta1/zz_generated.conversion.go
index a95e8f219..3ae4e0220 100644
--- a/apis/kueue/v1beta1/zz_generated.conversion.go
+++ b/apis/kueue/v1beta1/zz_generated.conversion.go
@@ -738,16 +738,6 @@ func RegisterConversions(s *runtime.Scheme) error {
 	}); err != nil {
 		return err
 	}
-	if err := s.AddGeneratedConversionFunc((*WorkloadSpec)(nil), (*v1beta2.WorkloadSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
-		return Convert_v1beta1_WorkloadSpec_To_v1beta2_WorkloadSpec(a.(*WorkloadSpec), b.(*v1beta2.WorkloadSpec), scope)
-	}); err != nil {
-		return err
-	}
-	if err := s.AddGeneratedConversionFunc((*v1beta2.WorkloadSpec)(nil), (*WorkloadSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
-		return Convert_v1beta2_WorkloadSpec_To_v1beta1_WorkloadSpec(a.(*v1beta2.WorkloadSpec), b.(*WorkloadSpec), scope)
-	}); err != nil {
-		return err
-	}
 	if err := s.AddConversionFunc((*AdmissionCheckSpec)(nil), (*v1beta2.AdmissionCheckSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
 		return Convert_v1beta1_AdmissionCheckSpec_To_v1beta2_AdmissionCheckSpec(a.(*AdmissionCheckSpec), b.(*v1beta2.AdmissionCheckSpec), scope)
 	}); err != nil {
@@ -768,6 +758,11 @@ func RegisterConversions(s *runtime.Scheme) error {
 	}); err != nil {
 		return err
 	}
+	if err := s.AddConversionFunc((*WorkloadSpec)(nil), (*v1beta2.WorkloadSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1beta1_WorkloadSpec_To_v1beta2_WorkloadSpec(a.(*WorkloadSpec), b.(*v1beta2.WorkloadSpec), scope)
+	}); err != nil {
+		return err
+	}
 	if err := s.AddConversionFunc((*WorkloadStatus)(nil), (*v1beta2.WorkloadStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
 		return Convert_v1beta1_WorkloadStatus_To_v1beta2_WorkloadStatus(a.(*WorkloadStatus), b.(*v1beta2.WorkloadStatus), scope)
 	}); err != nil {
@@ -783,6 +778,11 @@ func RegisterConversions(s *runtime.Scheme) error {
 	}); err != nil {
 		return err
 	}
+	if err := s.AddConversionFunc((*v1beta2.WorkloadSpec)(nil), (*WorkloadSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_v1beta2_WorkloadSpec_To_v1beta1_WorkloadSpec(a.(*v1beta2.WorkloadSpec), b.(*WorkloadSpec), scope)
+	}); err != nil {
+		return err
+	}
 	if err := s.AddConversionFunc((*v1beta2.WorkloadStatus)(nil), (*WorkloadStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
 		return Convert_v1beta2_WorkloadStatus_To_v1beta1_WorkloadStatus(a.(*v1beta2.WorkloadStatus), b.(*WorkloadStatus), scope)
 	}); err != nil {
@@ -2616,35 +2616,24 @@ func Convert_v1beta2_WorkloadSchedulingStatsEviction_To_v1beta1_WorkloadScheduli
 func autoConvert_v1beta1_WorkloadSpec_To_v1beta2_WorkloadSpec(in *WorkloadSpec, out *v1beta2.WorkloadSpec, s conversion.Scope) error {
 	out.PodSets = *(*[]v1beta2.PodSet)(unsafe.Pointer(&in.PodSets))
 	out.QueueName = v1beta2.LocalQueueName(in.QueueName)
-	out.PriorityClassName = in.PriorityClassName
+	// WARNING: in.PriorityClassName requires manual conversion: does not exist in peer-type
 	out.Priority = (*int32)(unsafe.Pointer(in.Priority))
-	out.PriorityClassSource = in.PriorityClassSource
+	// WARNING: in.PriorityClassSource requires manual conversion: does not exist in peer-type
 	out.Active = (*bool)(unsafe.Pointer(in.Active))
 	out.MaximumExecutionTimeSeconds = (*int32)(unsafe.Pointer(in.MaximumExecutionTimeSeconds))
 	return nil
 }
 
-// Convert_v1beta1_WorkloadSpec_To_v1beta2_WorkloadSpec is an autogenerated conversion function.
-func Convert_v1beta1_WorkloadSpec_To_v1beta2_WorkloadSpec(in *WorkloadSpec, out *v1beta2.WorkloadSpec, s conversion.Scope) error {
-	return autoConvert_v1beta1_WorkloadSpec_To_v1beta2_WorkloadSpec(in, out, s)
-}
-
 func autoConvert_v1beta2_WorkloadSpec_To_v1beta1_WorkloadSpec(in *v1beta2.WorkloadSpec, out *WorkloadSpec, s conversion.Scope) error {
 	out.PodSets = *(*[]PodSet)(unsafe.Pointer(&in.PodSets))
 	out.QueueName = LocalQueueName(in.QueueName)
-	out.PriorityClassName = in.PriorityClassName
+	// WARNING: in.PriorityClassRef requires manual conversion: does not exist in peer-type
 	out.Priority = (*int32)(unsafe.Pointer(in.Priority))
-	out.PriorityClassSource = in.PriorityClassSource
 	out.Active = (*bool)(unsafe.Pointer(in.Active))
 	out.MaximumExecutionTimeSeconds = (*int32)(unsafe.Pointer(in.MaximumExecutionTimeSeconds))
 	return nil
 }
 
-// Convert_v1beta2_WorkloadSpec_To_v1beta1_WorkloadSpec is an autogenerated conversion function.
-func Convert_v1beta2_WorkloadSpec_To_v1beta1_WorkloadSpec(in *v1beta2.WorkloadSpec, out *WorkloadSpec, s conversion.Scope) error {
-	return autoConvert_v1beta2_WorkloadSpec_To_v1beta1_WorkloadSpec(in, out, s)
-}
-
 func autoConvert_v1beta1_WorkloadStatus_To_v1beta2_WorkloadStatus(in *WorkloadStatus, out *v1beta2.WorkloadStatus, s conversion.Scope) error {
 	out.Conditions = *(*[]v1.Condition)(unsafe.Pointer(&in.Conditions))
 	out.Admission = (*v1beta2.Admission)(unsafe.Pointer(in.Admission))
diff --git a/apis/kueue/v1beta2/admissioncheck_types.go b/apis/kueue/v1beta2/admissioncheck_types.go
index 9ddb90f06..afd221185 100644
--- a/apis/kueue/v1beta2/admissioncheck_types.go
+++ b/apis/kueue/v1beta2/admissioncheck_types.go
@@ -52,7 +52,7 @@ type AdmissionCheckSpec struct {
 	// +kubebuilder:validation:XValidation:rule="self == oldSelf", message="field is immutable"
 	// +kubebuilder:validation:MaxLength=253
 	// +kubebuilder:validation:MinLength=1
-	ControllerName string `json:"controllerName"` //nolint:kubeapilinter // ignore omitempty
+	ControllerName string `json:"controllerName"`
 
 	// parameters identifies a configuration with additional parameters for the
 	// check.
@@ -116,11 +116,11 @@ type AdmissionCheck struct {
 
 	// spec is the specification of the AdmissionCheck.
 	// +optional
-	Spec AdmissionCheckSpec `json:"spec"` //nolint:kubeapilinter // spec should not be a pointer
+	Spec AdmissionCheckSpec `json:"spec"`
 
 	// status is the status of the AdmissionCheck.
 	// +optional
-	Status AdmissionCheckStatus `json:"status,omitempty"` //nolint:kubeapilinter // status should not be a pointer
+	Status AdmissionCheckStatus `json:"status,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/clusterqueue_types.go b/apis/kueue/v1beta2/clusterqueue_types.go
index 195497331..63549156a 100644
--- a/apis/kueue/v1beta2/clusterqueue_types.go
+++ b/apis/kueue/v1beta2/clusterqueue_types.go
@@ -31,7 +31,6 @@ const (
 	ClusterQueueActiveReasonAdmissionCheckInactive                   = "AdmissionCheckInactive"
 	ClusterQueueActiveReasonMultipleMultiKueueAdmissionChecks        = "MultipleMultiKueueAdmissionChecks"
 	ClusterQueueActiveReasonMultiKueueAdmissionCheckAppliedPerFlavor = "MultiKueueAdmissionCheckAppliedPerFlavor"
-	ClusterQueueActiveReasonNotSupportedWithTopologyAwareScheduling  = "NotSupportedWithTopologyAwareScheduling"
 	ClusterQueueActiveReasonTopologyNotFound                         = "TopologyNotFound"
 	ClusterQueueActiveReasonUnknown                                  = "Unknown"
 	ClusterQueueActiveReasonReady                                    = "Ready"
@@ -78,7 +77,7 @@ type ClusterQueueSpec struct {
 	// A cohort is a name that links CQs together, but it doesn't reference any
 	// object.
 	// +optional
-	CohortName CohortReference `json:"cohortName,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	CohortName CohortReference `json:"cohortName,omitempty"`
 
 	// queueingStrategy indicates the queueing strategy of the workloads
 	// across the queues in this ClusterQueue.
@@ -94,7 +93,7 @@ type ClusterQueueSpec struct {
 	// +optional
 	// +kubebuilder:default=BestEffortFIFO
 	// +kubebuilder:validation:Enum=StrictFIFO;BestEffortFIFO
-	QueueingStrategy QueueingStrategy `json:"queueingStrategy,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	QueueingStrategy QueueingStrategy `json:"queueingStrategy,omitempty"`
 
 	// namespaceSelector defines which namespaces are allowed to submit workloads to
 	// this clusterQueue. Beyond this basic support for policy, a policy agent like
@@ -217,7 +216,7 @@ type FlavorQuotas struct {
 	// ResourceFlavor. If a matching ResourceFlavor does not exist, the
 	// ClusterQueue will have an Active condition set to False.
 	// +required
-	Name ResourceFlavorReference `json:"name"` //nolint:kubeapilinter // should not be a pointer
+	Name ResourceFlavorReference `json:"name"`
 
 	// resources is the list of quotas for this flavor per resource.
 	// There could be up to 64 resources.
@@ -311,17 +310,17 @@ type ClusterQueueStatus struct {
 	// pendingWorkloads is the number of workloads currently waiting to be
 	// admitted to this clusterQueue.
 	// +optional
-	PendingWorkloads int32 `json:"pendingWorkloads"` //nolint:kubeapilinter // should not be a pointer
+	PendingWorkloads int32 `json:"pendingWorkloads"`
 
 	// reservingWorkloads is the number of workloads currently reserving quota in this
 	// clusterQueue.
 	// +optional
-	ReservingWorkloads int32 `json:"reservingWorkloads"` //nolint:kubeapilinter // should not be a pointer
+	ReservingWorkloads int32 `json:"reservingWorkloads"`
 
 	// admittedWorkloads is the number of workloads currently admitted to this
 	// clusterQueue and haven't finished yet.
 	// +optional
-	AdmittedWorkloads int32 `json:"admittedWorkloads"` //nolint:kubeapilinter // should not be a pointer
+	AdmittedWorkloads int32 `json:"admittedWorkloads"`
 
 	// fairSharing contains the current state for this ClusterQueue
 	// when participating in Fair Sharing.
@@ -333,7 +332,7 @@ type ClusterQueueStatus struct {
 type FlavorUsage struct {
 	// name of the flavor.
 	// +required
-	Name ResourceFlavorReference `json:"name,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	Name ResourceFlavorReference `json:"name,omitempty"`
 
 	// resources lists the quota usage for the resources in this flavor.
 	// +listType=map
@@ -351,12 +350,12 @@ type ResourceUsage struct {
 	// total is the total quantity of used quota, including the amount borrowed
 	// from the cohort.
 	// +optional
-	Total resource.Quantity `json:"total,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	Total resource.Quantity `json:"total,omitempty"`
 
 	// borrowed is quantity of quota that is borrowed from the cohort. In other
 	// words, it's the used quota that is over the nominalQuota.
 	// +optional
-	Borrowed resource.Quantity `json:"borrowed,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	Borrowed resource.Quantity `json:"borrowed,omitempty"`
 }
 
 const (
@@ -394,7 +393,7 @@ type FlavorFungibility struct {
 	// +kubebuilder:validation:Enum={MayStopSearch,TryNextFlavor}
 	// +kubebuilder:default="MayStopSearch"
 	// +optional
-	WhenCanBorrow FlavorFungibilityPolicy `json:"whenCanBorrow,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	WhenCanBorrow FlavorFungibilityPolicy `json:"whenCanBorrow,omitempty"`
 	// whenCanPreempt determines whether a workload should try the next flavor
 	// before borrowing in current flavor. The possible values are:
 	//
@@ -406,7 +405,7 @@ type FlavorFungibility struct {
 	// +kubebuilder:validation:Enum={MayStopSearch,TryNextFlavor}
 	// +kubebuilder:default="TryNextFlavor"
 	// +optional
-	WhenCanPreempt FlavorFungibilityPolicy `json:"whenCanPreempt,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	WhenCanPreempt FlavorFungibilityPolicy `json:"whenCanPreempt,omitempty"`
 }
 
 // ClusterQueuePreemption contains policies to preempt Workloads from this
@@ -450,7 +449,7 @@ type ClusterQueuePreemption struct {
 	// +optional
 	// +kubebuilder:default=Never
 	// +kubebuilder:validation:Enum=Never;LowerPriority;Any
-	ReclaimWithinCohort PreemptionPolicy `json:"reclaimWithinCohort,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	ReclaimWithinCohort PreemptionPolicy `json:"reclaimWithinCohort,omitempty"`
 
 	// borrowWithinCohort determines whether a pending Workload can preempt
 	// Workloads from other ClusterQueues in the cohort if the workload requires borrowing.
@@ -473,7 +472,7 @@ type ClusterQueuePreemption struct {
 	// +kubebuilder:default=Never
 	// +kubebuilder:validation:Enum=Never;LowerPriority;LowerOrNewerEqualPriority
 	// +optional
-	WithinClusterQueue PreemptionPolicy `json:"withinClusterQueue,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	WithinClusterQueue PreemptionPolicy `json:"withinClusterQueue,omitempty"`
 }
 
 type BorrowWithinCohortPolicy string
@@ -498,7 +497,7 @@ type BorrowWithinCohort struct {
 	// +kubebuilder:default=Never
 	// +kubebuilder:validation:Enum=Never;LowerPriority
 	// +optional
-	Policy BorrowWithinCohortPolicy `json:"policy,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	Policy BorrowWithinCohortPolicy `json:"policy,omitempty"`
 	// maxPriorityThreshold allows to restrict the set of workloads which
 	// might be preempted by a borrowing workload, to only workloads with
 	// priority less than or equal to the specified threshold priority.
@@ -528,10 +527,10 @@ type ClusterQueue struct {
 
 	// spec is the specification of the ClusterQueue.
 	// +optional
-	Spec ClusterQueueSpec `json:"spec,omitempty"` //nolint:kubeapilinter // spec should not be a pointer
+	Spec ClusterQueueSpec `json:"spec,omitempty"`
 	// status is the status of the ClusterQueue.
 	// +optional
-	Status ClusterQueueStatus `json:"status,omitempty"` //nolint:kubeapilinter // status should not be a pointer
+	Status ClusterQueueStatus `json:"status,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/cohort_types.go b/apis/kueue/v1beta2/cohort_types.go
index e53c824f3..8542b1097 100644
--- a/apis/kueue/v1beta2/cohort_types.go
+++ b/apis/kueue/v1beta2/cohort_types.go
@@ -33,7 +33,7 @@ type CohortSpec struct {
 	// removed.  We prevent further admission while the cycle
 	// exists.
 	// +optional
-	ParentName CohortReference `json:"parentName,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	ParentName CohortReference `json:"parentName,omitempty"`
 
 	// resourceGroups describes groupings of Resources and
 	// Flavors.  Each ResourceGroup defines a list of Resources
@@ -98,10 +98,10 @@ type Cohort struct {
 
 	// spec is the specification of the Cohort.
 	// +optional
-	Spec CohortSpec `json:"spec"` //nolint:kubeapilinter // spec should not be a pointer
+	Spec CohortSpec `json:"spec"`
 	// status is the status of the Cohort.
 	// +optional
-	Status CohortStatus `json:"status,omitempty"` //nolint:kubeapilinter // status should not be a pointer
+	Status CohortStatus `json:"status,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/fairsharing_types.go b/apis/kueue/v1beta2/fairsharing_types.go
index fbcb0bf97..2bab0cc89 100644
--- a/apis/kueue/v1beta2/fairsharing_types.go
+++ b/apis/kueue/v1beta2/fairsharing_types.go
@@ -55,7 +55,7 @@ type FairSharingStatus struct {
 	// weight of zero and is borrowing, this will return
 	// 9223372036854775807, the maximum possible share value.
 	// +required
-	WeightedShare int64 `json:"weightedShare"` //nolint:kubeapilinter // do not add omitempty
+	WeightedShare int64 `json:"weightedShare"`
 
 	// admissionFairSharingStatus represents information relevant to the Admission Fair Sharing
 	// +optional
@@ -67,11 +67,11 @@ type AdmissionFairSharingStatus struct {
 	// with decaying function applied.
 	// The value is populated if usage consumption functionality is enabled in Kueue config.
 	// +required
-	ConsumedResources corev1.ResourceList `json:"consumedResources"` //nolint:kubeapilinter // map type is required for standard Kubernetes ResourceList
+	ConsumedResources corev1.ResourceList `json:"consumedResources"`
 
 	// lastUpdate is the time when share and consumed resources were updated.
 	// +required
-	LastUpdate metav1.Time `json:"lastUpdate"` //nolint:kubeapilinter // exclude omitempty
+	LastUpdate metav1.Time `json:"lastUpdate"`
 }
 
 type AdmissionScope struct {
diff --git a/apis/kueue/v1beta2/localqueue_types.go b/apis/kueue/v1beta2/localqueue_types.go
index b6386d08b..e047c7367 100644
--- a/apis/kueue/v1beta2/localqueue_types.go
+++ b/apis/kueue/v1beta2/localqueue_types.go
@@ -34,7 +34,7 @@ type LocalQueueSpec struct {
 	// clusterQueue is a reference to a clusterQueue that backs this localQueue.
 	// +kubebuilder:validation:XValidation:rule="self == oldSelf", message="field is immutable"
 	// +optional
-	ClusterQueue ClusterQueueReference `json:"clusterQueue,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	ClusterQueue ClusterQueueReference `json:"clusterQueue,omitempty"`
 
 	// stopPolicy - if set to a value different from None, the LocalQueue is considered Inactive,
 	// no new reservation being made.
@@ -61,7 +61,7 @@ type TopologyInfo struct {
 	// name is the name of the topology.
 	//
 	// +required
-	Name TopologyReference `json:"name"` //nolint:kubeapilinter // should not be a pointer
+	Name TopologyReference `json:"name"`
 
 	// levels define the levels of topology.
 	//
@@ -88,17 +88,17 @@ type LocalQueueStatus struct {
 
 	// pendingWorkloads is the number of Workloads in the LocalQueue not yet admitted to a ClusterQueue
 	// +optional
-	PendingWorkloads int32 `json:"pendingWorkloads"` //nolint:kubeapilinter // should not be a pointer
+	PendingWorkloads int32 `json:"pendingWorkloads"`
 
 	// reservingWorkloads is the number of workloads in this LocalQueue
 	// reserving quota in a ClusterQueue and that haven't finished yet.
 	// +optional
-	ReservingWorkloads int32 `json:"reservingWorkloads"` //nolint:kubeapilinter // should not be a pointer
+	ReservingWorkloads int32 `json:"reservingWorkloads"`
 
 	// admittedWorkloads is the number of workloads in this LocalQueue
 	// admitted to a ClusterQueue and that haven't finished yet.
 	// +optional
-	AdmittedWorkloads int32 `json:"admittedWorkloads"` //nolint:kubeapilinter // should not be a pointer
+	AdmittedWorkloads int32 `json:"admittedWorkloads"`
 
 	// flavorsReservation are the reserved quotas, by flavor currently in use by the
 	// workloads assigned to this LocalQueue.
@@ -130,7 +130,7 @@ const (
 type LocalQueueFlavorUsage struct {
 	// name of the flavor.
 	// +required
-	Name ResourceFlavorReference `json:"name"` //nolint:kubeapilinter // should not be a pointer
+	Name ResourceFlavorReference `json:"name"`
 
 	// resources lists the quota usage for the resources in this flavor.
 	// +listType=map
@@ -147,7 +147,7 @@ type LocalQueueResourceUsage struct {
 
 	// total is the total quantity of used quota.
 	// +optional
-	Total resource.Quantity `json:"total,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	Total resource.Quantity `json:"total,omitempty"`
 }
 
 // +genclient
@@ -167,10 +167,10 @@ type LocalQueue struct {
 
 	// spec is the specification of the LocalQueue.
 	// +optional
-	Spec LocalQueueSpec `json:"spec"` //nolint:kubeapilinter // should not be a pointer
+	Spec LocalQueueSpec `json:"spec"`
 	// status is the status of the LocalQueue.
 	// +optional
-	Status LocalQueueStatus `json:"status,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	Status LocalQueueStatus `json:"status,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/multikueue_types.go b/apis/kueue/v1beta2/multikueue_types.go
index 629558cb3..e27f2c119 100644
--- a/apis/kueue/v1beta2/multikueue_types.go
+++ b/apis/kueue/v1beta2/multikueue_types.go
@@ -59,7 +59,7 @@ type KubeConfig struct {
 	// +kubebuilder:default=Secret
 	// +optional
 	// +kubebuilder:validation:Enum=Secret;Path
-	LocationType LocationType `json:"locationType"` //nolint:kubeapilinter // should not be a pointer
+	LocationType LocationType `json:"locationType"`
 }
 
 type MultiKueueClusterSpec struct {
@@ -98,11 +98,11 @@ type MultiKueueCluster struct {
 
 	// spec is the specification of the MultiKueueCluster.
 	// +optional
-	Spec MultiKueueClusterSpec `json:"spec,omitempty,omitzero"` //nolint:kubeapilinter // spec should not be a pointer
+	Spec MultiKueueClusterSpec `json:"spec,omitempty,omitzero"`
 
 	// status is the status of the MultiKueueCluster.
 	// +optional
-	Status MultiKueueClusterStatus `json:"status,omitempty"` //nolint:kubeapilinter // status should not be a pointer
+	Status MultiKueueClusterStatus `json:"status,omitempty"`
 }
 
 // +kubebuilder:object:root=true
@@ -140,7 +140,7 @@ type MultiKueueConfig struct {
 
 	// spec is the specification of the MultiKueueConfig.
 	// +optional
-	Spec MultiKueueConfigSpec `json:"spec,omitempty"` //nolint:kubeapilinter // spec should not be a pointer
+	Spec MultiKueueConfigSpec `json:"spec,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/provisioningrequestconfig_types.go b/apis/kueue/v1beta2/provisioningrequestconfig_types.go
index 2e3f75c1d..61c161913 100644
--- a/apis/kueue/v1beta2/provisioningrequestconfig_types.go
+++ b/apis/kueue/v1beta2/provisioningrequestconfig_types.go
@@ -171,7 +171,7 @@ type ProvisioningRequestConfig struct {
 
 	// spec is the specification of the ProvisioningRequestConfig.
 	// +optional
-	Spec ProvisioningRequestConfigSpec `json:"spec"` //nolint:kubeapilinter // should not be a pointer
+	Spec ProvisioningRequestConfigSpec `json:"spec"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/resourceflavor_types.go b/apis/kueue/v1beta2/resourceflavor_types.go
index e1dc74196..c5ea8eda7 100644
--- a/apis/kueue/v1beta2/resourceflavor_types.go
+++ b/apis/kueue/v1beta2/resourceflavor_types.go
@@ -35,7 +35,7 @@ type ResourceFlavor struct {
 
 	// spec is the specification of the ResourceFlavor.
 	// +optional
-	Spec ResourceFlavorSpec `json:"spec,omitempty"` //nolint:kubeapilinter // spec should not be a pointer
+	Spec ResourceFlavorSpec `json:"spec,omitempty"`
 }
 
 // TopologyReference is the name of the Topology.
@@ -105,7 +105,7 @@ type ResourceFlavorSpec struct {
 	// nodes matching to the Resource Flavor node labels.
 	//
 	// +optional
-	TopologyName *TopologyReference `json:"topologyName,omitempty"` //nolint:kubeapilinter // should be a pointer
+	TopologyName *TopologyReference `json:"topologyName,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/topology_types.go b/apis/kueue/v1beta2/topology_types.go
index e29b7350a..ab1a0df56 100644
--- a/apis/kueue/v1beta2/topology_types.go
+++ b/apis/kueue/v1beta2/topology_types.go
@@ -136,7 +136,7 @@ type Topology struct {
 
 	// spec is the specification of the Topology.
 	// +optional
-	Spec TopologySpec `json:"spec"` //nolint:kubeapilinter // spec should not be a pointer
+	Spec TopologySpec `json:"spec"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/workload_types.go b/apis/kueue/v1beta2/workload_types.go
index c2e9077cb..825eea6a6 100644
--- a/apis/kueue/v1beta2/workload_types.go
+++ b/apis/kueue/v1beta2/workload_types.go
@@ -24,7 +24,7 @@ import (
 )
 
 // WorkloadSpec defines the desired state of Workload
-// +kubebuilder:validation:XValidation:rule="has(self.priorityClassName) ? has(self.priority) : true", message="priority should not be nil when priorityClassName is set"
+// +kubebuilder:validation:XValidation:rule="!has(self.priorityClassRef) || has(self.priority)", message="priority should not be nil when priorityClassRef is set"
 type WorkloadSpec struct {
 	// podSets is a list of sets of homogeneous pods, each described by a Pod spec
 	// and a count.
@@ -36,42 +36,26 @@ type WorkloadSpec struct {
 	// +kubebuilder:validation:MaxItems=8
 	// +kubebuilder:validation:MinItems=1
 	// +optional
-	PodSets []PodSet `json:"podSets"` //nolint:kubeapilinter // do not add omitempty tag
+	PodSets []PodSet `json:"podSets"`
 
 	// queueName is the name of the LocalQueue the Workload is associated with.
 	// queueName cannot be changed while .status.admission is not null.
 	// +optional
-	QueueName LocalQueueName `json:"queueName,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	QueueName LocalQueueName `json:"queueName,omitempty"`
 
-	// priorityClassName is the name of the PriorityClass the Workload is associated with.
-	// If specified, indicates the workload's priority.
-	// "system-node-critical" and "system-cluster-critical" are two special
-	// keywords which indicate the highest priorities with the former being
-	// the highest priority. Any other name must be defined by creating a
-	// PriorityClass object with that name. If not specified, the workload
-	// priority will be default or zero if there is no default.
-	// +kubebuilder:validation:MaxLength=253
-	// +kubebuilder:validation:MinLength=1
-	// +kubebuilder:validation:Pattern="^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
+	// priorityClassRef references a PriorityClass object that defines the workload's priority.
+	//
 	// +optional
-	PriorityClassName string `json:"priorityClassName,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	PriorityClassRef *PriorityClassRef `json:"priorityClassRef,omitempty"`
 
 	// priority determines the order of access to the resources managed by the
 	// ClusterQueue where the workload is queued.
-	// The priority value is populated from PriorityClassName.
+	// The priority value is populated from the referenced PriorityClass (via priorityClassRef).
 	// The higher the value, the higher the priority.
-	// If priorityClassName is specified, priority must not be null.
+	// If priorityClassRef is specified, priority must not be null.
 	// +optional
 	Priority *int32 `json:"priority,omitempty"`
 
-	// priorityClassSource determines whether the priorityClass field refers to a pod PriorityClass or kueue.x-k8s.io/workloadpriorityclass.
-	// Workload's PriorityClass can accept the name of a pod priorityClass or a workloadPriorityClass.
-	// When using pod PriorityClass, a priorityClassSource field has the scheduling.k8s.io/priorityclass value.
-	// +kubebuilder:default=""
-	// +kubebuilder:validation:Enum=kueue.x-k8s.io/workloadpriorityclass;scheduling.k8s.io/priorityclass;""
-	// +optional
-	PriorityClassSource string `json:"priorityClassSource,omitempty"` //nolint:kubeapilinter // should not be a pointer
-
 	// active determines if a workload can be admitted into a queue.
 	// Changing active from true to false will evict any running workloads.
 	// Possible values are:
@@ -81,7 +65,7 @@ type WorkloadSpec struct {
 	//
 	// Defaults to true
 	// +kubebuilder:default=true
-	Active *bool `json:"active,omitempty"` //nolint:kubeapilinter // bool for the ease of use, inspired by k8s Job's Suspend field.
+	Active *bool `json:"active,omitempty"`
 
 	// maximumExecutionTimeSeconds if provided, determines the maximum time, in seconds,
 	// the workload can be admitted before it's automatically deactivated.
@@ -93,6 +77,81 @@ type WorkloadSpec struct {
 	MaximumExecutionTimeSeconds *int32 `json:"maximumExecutionTimeSeconds,omitempty"`
 }
 
+// PriorityClassGroup indicates the API group of the PriorityClass object.
+//
+// +enum
+// +kubebuilder:validation:Enum=kueue.x-k8s.io;scheduling.k8s.io
+type PriorityClassGroup string
+
+const (
+	// PodPriorityClassGroup represents the core Kubernetes scheduling group.
+	PodPriorityClassGroup PriorityClassGroup = "scheduling.k8s.io"
+
+	// WorkloadPriorityClassGroup represents the Kueue-specific priority group.
+	WorkloadPriorityClassGroup PriorityClassGroup = "kueue.x-k8s.io"
+)
+
+// PriorityClassKind is the kind of the PriorityClass object.
+//
+// +enum
+// +kubebuilder:validation:Enum=WorkloadPriorityClass;PriorityClass
+type PriorityClassKind string
+
+const (
+	// PodPriorityClassKind represents the core Kubernetes PriorityClass kind.
+	PodPriorityClassKind PriorityClassKind = "PriorityClass"
+
+	// WorkloadPriorityClassKind represents the Kueue WorkloadPriorityClass kind.
+	WorkloadPriorityClassKind PriorityClassKind = "WorkloadPriorityClass"
+)
+
+// NewPriorityClassRef creates a new PriorityClassRef with the specified group, kind, and name.
+func NewPriorityClassRef(group PriorityClassGroup, kind PriorityClassKind, name string) *PriorityClassRef {
+	return &PriorityClassRef{Group: group, Kind: kind, Name: name}
+}
+
+// NewWorkloadPriorityClassRef creates a PriorityClassRef for a WorkloadPriorityClass.
+func NewWorkloadPriorityClassRef(name string) *PriorityClassRef {
+	return NewPriorityClassRef(WorkloadPriorityClassGroup, WorkloadPriorityClassKind, name)
+}
+
+// NewPodPriorityClassRef creates a PriorityClassRef for a core Kubernetes PriorityClass.
+func NewPodPriorityClassRef(name string) *PriorityClassRef {
+	return NewPriorityClassRef(PodPriorityClassGroup, PodPriorityClassKind, name)
+}
+
+// PriorityClassRef references a PriorityClass in a specific API group.
+//
+// +kubebuilder:validation:XValidation:rule="(self.group == 'scheduling.k8s.io') ? self.kind == 'PriorityClass' : true", message="only the PriorityClass kind is allowed for the scheduling.k8s.io group"
+// +kubebuilder:validation:XValidation:rule="(self.group == 'kueue.x-k8s.io') ? self.kind == 'WorkloadPriorityClass' : true", message="only the WorkloadPriorityClass kind is allowed for the kueue.x-k8s.io group"
+type PriorityClassRef struct {
+	// group is the API group of the PriorityClass object.
+	// Use "kueue.x-k8s.io" for WorkloadPriorityClass.
+	// Use "scheduling.k8s.io" for Pod PriorityClass.
+	//
+	// +required
+	Group PriorityClassGroup `json:"group,omitempty"`
+
+	// kind is the kind of the PriorityClass object.
+	//
+	// +required
+	Kind PriorityClassKind `json:"kind,omitempty"`
+
+	// name is the name of the PriorityClass the Workload is associated with.
+	// If specified, indicates the workload's priority.
+	// "system-node-critical" and "system-cluster-critical" are two special
+	// keywords which indicate the highest priorities with the former being
+	// the highest priority. Any other name must be defined by creating a
+	// PriorityClass object with that name. If not specified, the workload
+	// priority will be default or zero if there is no default.
+	//
+	// +required
+	// +kubebuilder:validation:MaxLength=253
+	// +kubebuilder:validation:MinLength=1
+	// +kubebuilder:validation:Pattern="^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$"
+	Name string `json:"name,omitempty"`
+}
+
 // PodSetTopologyRequest defines the topology request for a PodSet.
 type PodSetTopologyRequest struct {
 	// required indicates the topology level required by the PodSet, as
@@ -119,7 +178,7 @@ type PodSetTopologyRequest struct {
 	//
 	// +optional
 	// +kubebuilder:validation:Type=boolean
-	Unconstrained *bool `json:"unconstrained,omitempty"` //nolint:kubeapilinter // disabling to avoid changing existing API
+	Unconstrained *bool `json:"unconstrained,omitempty"`
 
 	// podIndexLabel indicates the name of the label indexing the pods.
 	// For example, in the context of
@@ -169,14 +228,14 @@ type PodSetTopologyRequest struct {
 type Admission struct {
 	// clusterQueue is the name of the ClusterQueue that admitted this workload.
 	// +optional
-	ClusterQueue ClusterQueueReference `json:"clusterQueue"` //nolint:kubeapilinter // should not be a pointer
+	ClusterQueue ClusterQueueReference `json:"clusterQueue"`
 
 	// podSetAssignments hold the admission results for each of the .spec.podSets entries.
 	// +listType=map
 	// +listMapKey=name
 	// +kubebuilder:validation:MaxItems=8
 	// +optional
-	PodSetAssignments []PodSetAssignment `json:"podSetAssignments"` //nolint:kubeapilinter // do not add omitempty
+	PodSetAssignments []PodSetAssignment `json:"podSetAssignments"`
 }
 
 // PodSetReference is the name of a PodSet.
@@ -192,7 +251,7 @@ type PodSetAssignment struct {
 	// name is the name of the podSet. It should match one of the names in .spec.podSets.
 	// +kubebuilder:default=main
 	// +optional
-	Name PodSetReference `json:"name"` //nolint:kubeapilinter // should not be a pointer
+	Name PodSetReference `json:"name"`
 
 	// flavors are the flavors assigned to the workload for each resource.
 	// +optional
@@ -204,7 +263,7 @@ type PodSetAssignment struct {
 	// the LimitRange defaults and RuntimeClass overheads at the moment of admission.
 	// This field will not change in case of quota reclaim.
 	// +optional
-	ResourceUsage corev1.ResourceList `json:"resourceUsage,omitempty"` //nolint:kubeapilinter // map type is required for standard Kubernetes ResourceList
+	ResourceUsage corev1.ResourceList `json:"resourceUsage,omitempty"`
 
 	// count is the number of pods taken into account at admission time.
 	// This field will not change in case of quota reclaim.
@@ -276,15 +335,15 @@ type PodSetAssignment struct {
 
 // DelayedTopologyRequestState indicates the state of the delayed TopologyRequest.
 // +enum
-// +kubebuilder:validation:enum=Pending;Ready
+// +kubebuilder:validation:Enum=Pending;Ready
 // +kubebuilder:validation:MaxLength=7
 type DelayedTopologyRequestState string
 
 const (
-	// This state indicates the delayed TopologyRequest is waiting for determining.
+	// DelayedTopologyRequestStatePending indicates the delayed TopologyRequest is waiting for determining.
 	DelayedTopologyRequestStatePending DelayedTopologyRequestState = "Pending"
 
-	// This state indicates the delayed TopologyRequest is was requested and completed.
+	// DelayedTopologyRequestStateReady indicates the delayed TopologyRequest is was requested and completed.
 	DelayedTopologyRequestStateReady DelayedTopologyRequestState = "Ready"
 )
 
@@ -334,7 +393,7 @@ type PodSet struct {
 	// name is the PodSet name.
 	// +kubebuilder:default=main
 	// +optional
-	Name PodSetReference `json:"name,omitempty"` //nolint:kubeapilinter // should not be a pointer
+	Name PodSetReference `json:"name,omitempty"`
 
 	// template is the Pod template.
 	//
@@ -356,7 +415,7 @@ type PodSet struct {
 	// +kubebuilder:default=1
 	// +kubebuilder:validation:Minimum=0
 	// +optional
-	Count int32 `json:"count"` //nolint:kubeapilinter // should not be a pointer
+	Count int32 `json:"count"`
 
 	// minCount is the minimum number of pods for the spec acceptable
 	// if the workload supports partial admission.
@@ -509,19 +568,19 @@ type WorkloadSchedulingStatsEviction struct {
 	//
 	// +required
 	// +kubebuilder:validation:MaxLength=316
-	Reason string `json:"reason"` //nolint:kubeapilinter // should not be a pointer
+	Reason string `json:"reason"`
 
 	// underlyingCause specifies a finer-grained explanation that complements the eviction reason.
 	// This may be an empty string.
 	//
 	// +required
-	UnderlyingCause EvictionUnderlyingCause `json:"underlyingCause"` //nolint:kubeapilinter // should not be a pointer
+	UnderlyingCause EvictionUnderlyingCause `json:"underlyingCause"`
 
 	// count tracks the number of evictions for this reason and detailed reason.
 	//
 	// +required
 	// +kubebuilder:validation:Minimum=0
-	Count int32 `json:"count"` //nolint:kubeapilinter // should not be a pointer
+	Count int32 `json:"count"`
 }
 
 type UnhealthyNode struct {
@@ -529,7 +588,7 @@ type UnhealthyNode struct {
 	//
 	// +required
 	// +kubebuilder:validation:MaxLength=63
-	Name string `json:"name"` //nolint:kubeapilinter // should not be a pointer
+	Name string `json:"name"`
 }
 
 type RequeueState struct {
@@ -572,7 +631,7 @@ type AdmissionCheckState struct {
 	// This may be an empty string.
 	// +required
 	// +kubebuilder:validation:MaxLength=32768
-	Message string `json:"message" protobuf:"bytes,6,opt,name=message"` //nolint:kubeapilinter // disable should be a pointer rule
+	Message string `json:"message" protobuf:"bytes,6,opt,name=message"`
 
 	// podSetUpdates contains a list of pod set modifications suggested by AdmissionChecks.
 	// +optional
@@ -588,7 +647,7 @@ type AdmissionCheckState struct {
 type PodSetUpdate struct {
 	// name of the PodSet to modify. Should match to one of the Workload's PodSets.
 	// +required
-	Name PodSetReference `json:"name"` //nolint:kubeapilinter // duplicatemarkers seems to say these are duplicates
+	Name PodSetReference `json:"name"`
 
 	// labels of the PodSet to modify.
 	// +optional
@@ -617,18 +676,18 @@ type PodSetUpdate struct {
 type ReclaimablePod struct {
 	// name is the PodSet name.
 	// +required
-	Name PodSetReference `json:"name"` //nolint:kubeapilinter // duplicatemarkers seems to say these are duplicates
+	Name PodSetReference `json:"name"`
 
 	// count is the number of pods for which the requested resources are no longer needed.
 	// +kubebuilder:validation:Minimum=0
 	// +required
-	Count int32 `json:"count"` //nolint:kubeapilinter // should not be a pointer
+	Count int32 `json:"count"`
 }
 
 type PodSetRequest struct {
 	// name is the name of the podSet. It should match one of the names in .spec.podSets.
 	// +required
-	Name PodSetReference `json:"name"` //nolint:kubeapilinter // duplicatemarkers seems to say these are duplicates
+	Name PodSetReference `json:"name"`
 
 	// resources is the total resources all the pods in the podset need to run.
 	//
@@ -636,7 +695,7 @@ type PodSetRequest struct {
 	// the LimitRange defaults and RuntimeClass overheads at the moment of consideration
 	// and the application of resource.excludeResourcePrefixes and resource.transformations.
 	// +optional
-	Resources corev1.ResourceList `json:"resources,omitempty"` //nolint:kubeapilinter // map type is required for standard Kubernetes ResourceList
+	Resources corev1.ResourceList `json:"resources,omitempty"`
 }
 
 const (
@@ -800,8 +859,10 @@ const (
 
 // Workload is the Schema for the workloads API
 // +kubebuilder:validation:XValidation:rule="has(self.status) && has(self.status.conditions) && self.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True') && has(self.status.admission) ? size(self.spec.podSets) == size(self.status.admission.podSetAssignments) : true", message="podSetAssignments must have the same number of podSets as the spec"
-// +kubebuilder:validation:XValidation:rule="(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True')) ? ((!has(self.spec.priorityClassSource) && !has(oldSelf.spec.priorityClassSource)) || (has(self.spec.priorityClassSource) && has(oldSelf.spec.priorityClassSource) && self.spec.priorityClassSource == oldSelf.spec.priorityClassSource) || (!has(self.spec.priorityClassSource) && has(oldSelf.spec.priorityClassSource) && oldSelf.spec.priorityClassSource.size() == 0) || (!has(oldSelf.spec.priorityClassSource) && has(self.spec.priorityClassSource) && self.spec.priorityClassSource.size() == 0)) : true", message="priorityClassSource is immutable while workload quota reserved"
-// +kubebuilder:validation:XValidation:rule="(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True') && (self.spec.priorityClassSource != 'kueue.x-k8s.io/workloadpriorityclass') && has(oldSelf.spec.priorityClassName) && has(self.spec.priorityClassName)) ? (oldSelf.spec.priorityClassName == self.spec.priorityClassName) : true", message="priorityClassName is immutable while workload quota reserved and priorityClassSource is not equal to kueue.x-k8s.io/workloadpriorityclass"
+// +kubebuilder:validation:XValidation:rule="(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True')) ? (!has(oldSelf.spec.priorityClassRef) && !has(self.spec.priorityClassRef)) || (has(oldSelf.spec.priorityClassRef) && has(self.spec.priorityClassRef)) : true",message="priorityClassRef is immutable while workload quota reserved"
+// +kubebuilder:validation:XValidation:rule="(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True') && has(oldSelf.spec.priorityClassRef) && has(self.spec.priorityClassRef)) ? oldSelf.spec.priorityClassRef.group == self.spec.priorityClassRef.group : true",message="priorityClassRef.group is immutable while workload quota reserved"
+// +kubebuilder:validation:XValidation:rule="(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True') && has(oldSelf.spec.priorityClassRef) && has(self.spec.priorityClassRef)) ? oldSelf.spec.priorityClassRef.kind == self.spec.priorityClassRef.kind : true",message="priorityClassRef.kind is immutable while workload quota reserved"
+// +kubebuilder:validation:XValidation:rule="(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True') && has(oldSelf.spec.priorityClassRef) && has(self.spec.priorityClassRef) && self.spec.priorityClassRef.group == 'scheduling.k8s.io' && self.spec.priorityClassRef.kind == 'PriorityClass') ? oldSelf.spec.priorityClassRef.name == self.spec.priorityClassRef.name : true",message="priorityClassRef.name is immutable for scheduling.k8s.io/priorityclass while workload quota reserved"
 // +kubebuilder:validation:XValidation:rule="(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True')) && (has(self.status) && has(self.status.conditions) && self.status.conditions.exists(c, c.type == 'QuotaReserved' && c.status == 'True')) && has(oldSelf.spec.queueName) && has(self.spec.queueName) ? oldSelf.spec.queueName == self.spec.queueName : true", message="queueName is immutable while workload quota reserved"
 // +kubebuilder:validation:XValidation:rule="((has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == 'Admitted' && c.status == 'True')) && (has(self.status) && has(self.status.conditions) && self.status.conditions.exists(c, c.type == 'Admitted' && c.status == 'True')))?((has(oldSelf.spec.maximumExecutionTimeSeconds)?oldSelf.spec.maximumExecutionTimeSeconds:0) ==  (has(self.spec.maximumExecutionTimeSeconds)?self.spec.maximumExecutionTimeSeconds:0)):true", message="maximumExecutionTimeSeconds is immutable while workload quota reserved"
 type Workload struct {
@@ -812,10 +873,10 @@ type Workload struct {
 
 	// spec is the specification of the Workload.
 	// +optional
-	Spec WorkloadSpec `json:"spec"` //nolint:kubeapilinter // spec should not be a pointer
+	Spec WorkloadSpec `json:"spec"`
 	// status is the status of the Workload.
 	// +optional
-	Status WorkloadStatus `json:"status,omitempty"` //nolint:kubeapilinter // status should not be a pointer
+	Status WorkloadStatus `json:"status,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/workloadpriorityclass_types.go b/apis/kueue/v1beta2/workloadpriorityclass_types.go
index c6727a659..49c0e3e57 100644
--- a/apis/kueue/v1beta2/workloadpriorityclass_types.go
+++ b/apis/kueue/v1beta2/workloadpriorityclass_types.go
@@ -37,14 +37,14 @@ type WorkloadPriorityClass struct {
 	// receive when jobs have the name of this class in their workloadPriorityClass label.
 	// Changing the value of workloadPriorityClass doesn't affect the priority of workloads that were already created.
 	// +required
-	Value int32 `json:"value"` //nolint:kubeapilinter // disabling should be a pointer
+	Value int32 `json:"value"`
 
 	// description is an arbitrary string that usually provides guidelines on
 	// when this workloadPriorityClass should be used.
 	// The description is limited to a maximum of 2048 characters.
 	// +optional
 	// +kubebuilder:validation:MaxLength=2048
-	Description string `json:"description,omitempty"` //nolint:kubeapilinter // disabling should not be a pointer
+	Description string `json:"description,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/kueue/v1beta2/zz_generated.deepcopy.go b/apis/kueue/v1beta2/zz_generated.deepcopy.go
index b641161ba..77a57cd69 100644
--- a/apis/kueue/v1beta2/zz_generated.deepcopy.go
+++ b/apis/kueue/v1beta2/zz_generated.deepcopy.go
@@ -1217,6 +1217,21 @@ func (in *PodSetUpdate) DeepCopy() *PodSetUpdate {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *PriorityClassRef) DeepCopyInto(out *PriorityClassRef) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PriorityClassRef.
+func (in *PriorityClassRef) DeepCopy() *PriorityClassRef {
+	if in == nil {
+		return nil
+	}
+	out := new(PriorityClassRef)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *ProvisioningRequestConfig) DeepCopyInto(out *ProvisioningRequestConfig) {
 	*out = *in
@@ -1926,6 +1941,11 @@ func (in *WorkloadSpec) DeepCopyInto(out *WorkloadSpec) {
 			(*in)[i].DeepCopyInto(&(*out)[i])
 		}
 	}
+	if in.PriorityClassRef != nil {
+		in, out := &in.PriorityClassRef, &out.PriorityClassRef
+		*out = new(PriorityClassRef)
+		**out = **in
+	}
 	if in.Priority != nil {
 		in, out := &in.Priority, &out.Priority
 		*out = new(int32)
diff --git a/charts/kueue/templates/crd/kueue.x-k8s.io_workloads.yaml b/charts/kueue/templates/crd/kueue.x-k8s.io_workloads.yaml
index 4659b61c8..aba263826 100644
--- a/charts/kueue/templates/crd/kueue.x-k8s.io_workloads.yaml
+++ b/charts/kueue/templates/crd/kueue.x-k8s.io_workloads.yaml
@@ -17119,35 +17119,52 @@ spec:
                   description: |-
                     priority determines the order of access to the resources managed by the
                     ClusterQueue where the workload is queued.
-                    The priority value is populated from PriorityClassName.
+                    The priority value is populated from the referenced PriorityClass (via priorityClassRef).
                     The higher the value, the higher the priority.
-                    If priorityClassName is specified, priority must not be null.
+                    If priorityClassRef is specified, priority must not be null.
                   format: int32
                   type: integer
-                priorityClassName:
-                  description: |-
-                    priorityClassName is the name of the PriorityClass the Workload is associated with.
-                    If specified, indicates the workload's priority.
-                    "system-node-critical" and "system-cluster-critical" are two special
-                    keywords which indicate the highest priorities with the former being
-                    the highest priority. Any other name must be defined by creating a
-                    PriorityClass object with that name. If not specified, the workload
-                    priority will be default or zero if there is no default.
-                  maxLength: 253
-                  minLength: 1
-                  pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                  type: string
-                priorityClassSource:
-                  default: ""
-                  description: |-
-                    priorityClassSource determines whether the priorityClass field refers to a pod PriorityClass or kueue.x-k8s.io/workloadpriorityclass.
-                    Workload's PriorityClass can accept the name of a pod priorityClass or a workloadPriorityClass.
-                    When using pod PriorityClass, a priorityClassSource field has the scheduling.k8s.io/priorityclass value.
-                  enum:
-                    - kueue.x-k8s.io/workloadpriorityclass
-                    - scheduling.k8s.io/priorityclass
-                    - ""
-                  type: string
+                priorityClassRef:
+                  description: priorityClassRef references a PriorityClass object that defines the workload's priority.
+                  properties:
+                    group:
+                      description: |-
+                        group is the API group of the PriorityClass object.
+                        Use "kueue.x-k8s.io" for WorkloadPriorityClass.
+                        Use "scheduling.k8s.io" for Pod PriorityClass.
+                      enum:
+                        - kueue.x-k8s.io
+                        - scheduling.k8s.io
+                      type: string
+                    kind:
+                      description: kind is the kind of the PriorityClass object.
+                      enum:
+                        - WorkloadPriorityClass
+                        - PriorityClass
+                      type: string
+                    name:
+                      description: |-
+                        name is the name of the PriorityClass the Workload is associated with.
+                        If specified, indicates the workload's priority.
+                        "system-node-critical" and "system-cluster-critical" are two special
+                        keywords which indicate the highest priorities with the former being
+                        the highest priority. Any other name must be defined by creating a
+                        PriorityClass object with that name. If not specified, the workload
+                        priority will be default or zero if there is no default.
+                      maxLength: 253
+                      minLength: 1
+                      pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                      type: string
+                  required:
+                    - group
+                    - kind
+                    - name
+                  type: object
+                  x-kubernetes-validations:
+                    - message: only the PriorityClass kind is allowed for the scheduling.k8s.io group
+                      rule: '(self.group == ''scheduling.k8s.io'') ? self.kind == ''PriorityClass'' : true'
+                    - message: only the WorkloadPriorityClass kind is allowed for the kueue.x-k8s.io group
+                      rule: '(self.group == ''kueue.x-k8s.io'') ? self.kind == ''WorkloadPriorityClass'' : true'
                 queueName:
                   description: |-
                     queueName is the name of the LocalQueue the Workload is associated with.
@@ -17157,8 +17174,8 @@ spec:
                   type: string
               type: object
               x-kubernetes-validations:
-                - message: priority should not be nil when priorityClassName is set
-                  rule: 'has(self.priorityClassName) ? has(self.priority) : true'
+                - message: priority should not be nil when priorityClassRef is set
+                  rule: '!has(self.priorityClassRef) || has(self.priority)'
             status:
               description: status is the status of the Workload.
               properties:
@@ -17200,6 +17217,9 @@ spec:
                               Kueue schedules the second pass of scheduling for each workload with at
                               least one PodSet which has delayedTopologyRequest=true and without
                               topologyAssignment.
+                            enum:
+                              - Pending
+                              - Ready
                             maxLength: 7
                             type: string
                           flavors:
@@ -17697,10 +17717,14 @@ spec:
           x-kubernetes-validations:
             - message: podSetAssignments must have the same number of podSets as the spec
               rule: 'has(self.status) && has(self.status.conditions) && self.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'') && has(self.status.admission) ? size(self.spec.podSets) == size(self.status.admission.podSetAssignments) : true'
-            - message: priorityClassSource is immutable while workload quota reserved
-              rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'')) ? ((!has(self.spec.priorityClassSource) && !has(oldSelf.spec.priorityClassSource)) || (has(self.spec.priorityClassSource) && has(oldSelf.spec.priorityClassSource) && self.spec.priorityClassSource == oldSelf.spec.priorityClassSource) || (!has(self.spec.priorityClassSource) && has(oldSelf.spec.priorityClassSource) && oldSelf.spec.priorityClassSource.size() == 0) || (!has(oldSelf.spec.priorityClassSource) && has(self.spec.priorityClassSource) && self.spec.priorityClassSource.size() == 0)) : true'
-            - message: priorityClassName is immutable while workload quota reserved and priorityClassSource is not equal to kueue.x-k8s.io/workloadpriorityclass
-              rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'') && (self.spec.priorityClassSource != ''kueue.x-k8s.io/workloadpriorityclass'') && has(oldSelf.spec.priorityClassName) && has(self.spec.priorityClassName)) ? (oldSelf.spec.priorityClassName == self.spec.priorityClassName) : true'
+            - message: priorityClassRef is immutable while workload quota reserved
+              rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'')) ? (!has(oldSelf.spec.priorityClassRef) && !has(self.spec.priorityClassRef)) || (has(oldSelf.spec.priorityClassRef) && has(self.spec.priorityClassRef)) : true'
+            - message: priorityClassRef.group is immutable while workload quota reserved
+              rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'') && has(oldSelf.spec.priorityClassRef) && has(self.spec.priorityClassRef)) ? oldSelf.spec.priorityClassRef.group == self.spec.priorityClassRef.group : true'
+            - message: priorityClassRef.kind is immutable while workload quota reserved
+              rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'') && has(oldSelf.spec.priorityClassRef) && has(self.spec.priorityClassRef)) ? oldSelf.spec.priorityClassRef.kind == self.spec.priorityClassRef.kind : true'
+            - message: priorityClassRef.name is immutable for scheduling.k8s.io/priorityclass while workload quota reserved
+              rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'') && has(oldSelf.spec.priorityClassRef) && has(self.spec.priorityClassRef) && self.spec.priorityClassRef.group == ''scheduling.k8s.io'' && self.spec.priorityClassRef.kind == ''PriorityClass'') ? oldSelf.spec.priorityClassRef.name == self.spec.priorityClassRef.name : true'
             - message: queueName is immutable while workload quota reserved
               rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'')) && (has(self.status) && has(self.status.conditions) && self.status.conditions.exists(c, c.type == ''QuotaReserved'' && c.status == ''True'')) && has(oldSelf.spec.queueName) && has(self.spec.queueName) ? oldSelf.spec.queueName == self.spec.queueName : true'
             - message: maximumExecutionTimeSeconds is immutable while workload quota reserved
diff --git a/client-go/applyconfiguration/kueue/v1beta2/priorityclassref.go b/client-go/applyconfiguration/kueue/v1beta2/priorityclassref.go
new file mode 100644
index 000000000..6f31340a9
--- /dev/null
+++ b/client-go/applyconfiguration/kueue/v1beta2/priorityclassref.go
@@ -0,0 +1,60 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+// Code generated by applyconfiguration-gen. DO NOT EDIT.
+
+package v1beta2
+
+import (
+	kueuev1beta2 "sigs.k8s.io/kueue/apis/kueue/v1beta2"
+)
+
+// PriorityClassRefApplyConfiguration represents a declarative configuration of the PriorityClassRef type for use
+// with apply.
+type PriorityClassRefApplyConfiguration struct {
+	Group *kueuev1beta2.PriorityClassGroup `json:"group,omitempty"`
+	Kind  *kueuev1beta2.PriorityClassKind  `json:"kind,omitempty"`
+	Name  *string                          `json:"name,omitempty"`
+}
+
+// PriorityClassRefApplyConfiguration constructs a declarative configuration of the PriorityClassRef type for use with
+// apply.
+func PriorityClassRef() *PriorityClassRefApplyConfiguration {
+	return &PriorityClassRefApplyConfiguration{}
+}
+
+// WithGroup sets the Group field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Group field is set to the value of the last call.
+func (b *PriorityClassRefApplyConfiguration) WithGroup(value kueuev1beta2.PriorityClassGroup) *PriorityClassRefApplyConfiguration {
+	b.Group = &value
+	return b
+}
+
+// WithKind sets the Kind field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Kind field is set to the value of the last call.
+func (b *PriorityClassRefApplyConfiguration) WithKind(value kueuev1beta2.PriorityClassKind) *PriorityClassRefApplyConfiguration {
+	b.Kind = &value
+	return b
+}
+
+// WithName sets the Name field in the declarative configuration to the given value
+// and returns the receiver, so that objects can be built by chaining "With" function invocations.
+// If called multiple times, the Name field is set to the value of the last call.
+func (b *PriorityClassRefApplyConfiguration) WithName(value string) *PriorityClassRefApplyConfiguration {
+	b.Name = &value
+	return b
+}
diff --git a/client-go/applyconfiguration/kueue/v1beta2/workloadspec.go b/client-go/applyconfiguration/kueue/v1beta2/workloadspec.go
index ac14b4706..ab7c0b9ea 100644
--- a/client-go/applyconfiguration/kueue/v1beta2/workloadspec.go
+++ b/client-go/applyconfiguration/kueue/v1beta2/workloadspec.go
@@ -24,13 +24,12 @@ import (
 // WorkloadSpecApplyConfiguration represents a declarative configuration of the WorkloadSpec type for use
 // with apply.
 type WorkloadSpecApplyConfiguration struct {
-	PodSets                     []PodSetApplyConfiguration   `json:"podSets,omitempty"`
-	QueueName                   *kueuev1beta2.LocalQueueName `json:"queueName,omitempty"`
-	PriorityClassName           *string                      `json:"priorityClassName,omitempty"`
-	Priority                    *int32                       `json:"priority,omitempty"`
-	PriorityClassSource         *string                      `json:"priorityClassSource,omitempty"`
-	Active                      *bool                        `json:"active,omitempty"`
-	MaximumExecutionTimeSeconds *int32                       `json:"maximumExecutionTimeSeconds,omitempty"`
+	PodSets                     []PodSetApplyConfiguration          `json:"podSets,omitempty"`
+	QueueName                   *kueuev1beta2.LocalQueueName        `json:"queueName,omitempty"`
+	PriorityClassRef            *PriorityClassRefApplyConfiguration `json:"priorityClassRef,omitempty"`
+	Priority                    *int32                              `json:"priority,omitempty"`
+	Active                      *bool                               `json:"active,omitempty"`
+	MaximumExecutionTimeSeconds *int32                              `json:"maximumExecutionTimeSeconds,omitempty"`
 }
 
 // WorkloadSpecApplyConfiguration constructs a declarative configuration of the WorkloadSpec type for use with
@@ -60,11 +59,11 @@ func (b *WorkloadSpecApplyConfiguration) WithQueueName(value kueuev1beta2.LocalQ
 	return b
 }
 
-// WithPriorityClassName sets the PriorityClassName field in the declarative configuration to the given value
+// WithPriorityClassRef sets the PriorityClassRef field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the PriorityClassName field is set to the value of the last call.
-func (b *WorkloadSpecApplyConfiguration) WithPriorityClassName(value string) *WorkloadSpecApplyConfiguration {
-	b.PriorityClassName = &value
+// If called multiple times, the PriorityClassRef field is set to the value of the last call.
+func (b *WorkloadSpecApplyConfiguration) WithPriorityClassRef(value *PriorityClassRefApplyConfiguration) *WorkloadSpecApplyConfiguration {
+	b.PriorityClassRef = value
 	return b
 }
 
@@ -76,14 +75,6 @@ func (b *WorkloadSpecApplyConfiguration) WithPriority(value int32) *WorkloadSpec
 	return b
 }
 
-// WithPriorityClassSource sets the PriorityClassSource field in the declarative configuration to the given value
-// and returns the receiver, so that objects can be built by chaining "With" function invocations.
-// If called multiple times, the PriorityClassSource field is set to the value of the last call.
-func (b *WorkloadSpecApplyConfiguration) WithPriorityClassSource(value string) *WorkloadSpecApplyConfiguration {
-	b.PriorityClassSource = &value
-	return b
-}
-
 // WithActive sets the Active field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Active field is set to the value of the last call.
diff --git a/client-go/applyconfiguration/utils.go b/client-go/applyconfiguration/utils.go
index ad820f3af..162c4b523 100644
--- a/client-go/applyconfiguration/utils.go
+++ b/client-go/applyconfiguration/utils.go
@@ -251,6 +251,8 @@ func ForKind(kind schema.GroupVersionKind) interface{} {
 		return &kueuev1beta2.PodSetTopologyRequestApplyConfiguration{}
 	case v1beta2.SchemeGroupVersion.WithKind("PodSetUpdate"):
 		return &kueuev1beta2.PodSetUpdateApplyConfiguration{}
+	case v1beta2.SchemeGroupVersion.WithKind("PriorityClassRef"):
+		return &kueuev1beta2.PriorityClassRefApplyConfiguration{}
 	case v1beta2.SchemeGroupVersion.WithKind("ProvisioningRequestConfig"):
 		return &kueuev1beta2.ProvisioningRequestConfigApplyConfiguration{}
 	case v1beta2.SchemeGroupVersion.WithKind("ProvisioningRequestConfigSpec"):
diff --git a/cmd/importer/pod/import.go b/cmd/importer/pod/import.go
index 6cadf7a7d..8ffa694ee 100644
--- a/cmd/importer/pod/import.go
+++ b/cmd/importer/pod/import.go
@@ -80,9 +80,8 @@ func Import(ctx context.Context, c client.Client, cache *util.ImportCache, jobs
 		maps.Copy(wl.Labels, cache.AddLabels)
 
 		if pc, found := cache.PriorityClasses[p.Spec.PriorityClassName]; found {
-			wl.Spec.PriorityClassName = pc.Name
+			wl.Spec.PriorityClassRef = kueuev1beta2.NewPodPriorityClassRef(pc.Name)
 			wl.Spec.Priority = &pc.Value
-			wl.Spec.PriorityClassSource = constants.PodPriorityClassSource
 		}
 
 		wlv1beta1 := &kueue.Workload{
diff --git a/cmd/kueueviz/frontend/package-lock.json b/cmd/kueueviz/frontend/package-lock.json
index 5e0232b99..1edabfb57 100644
--- a/cmd/kueueviz/frontend/package-lock.json
+++ b/cmd/kueueviz/frontend/package-lock.json
@@ -11,19 +11,19 @@
       "dependencies": {
         "@emotion/react": "^11.14.0",
         "@emotion/styled": "^11.14.1",
-        "@mui/icons-material": "^7.3.4",
+        "@mui/icons-material": "^7.3.5",
         "@mui/material": "^7.3.1",
         "ace-builds": "^1.43.4",
         "react": "^19.2.0",
         "react-ace": "^14.0.1",
         "react-dom": "^19.2.0",
-        "react-router-dom": "^7.9.4",
+        "react-router-dom": "^7.9.5",
         "react-toastify": "^11.0.5"
       },
       "devDependencies": {
         "@vitejs/plugin-react": "^5.1.0",
         "depcheck": "^1.4.7",
-        "vite": "^7.1.12"
+        "vite": "^7.2.2"
       }
     },
     "node_modules/@babel/code-frame": {
@@ -924,9 +924,9 @@
       }
     },
     "node_modules/@mui/core-downloads-tracker": {
-      "version": "7.3.4",
-      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.4.tgz",
-      "integrity": "sha512-BIktMapG3r4iXwIhYNpvk97ZfYWTreBBQTWjQKbNbzI64+ULHfYavQEX2w99aSWHS58DvXESWIgbD9adKcUOBw==",
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-7.3.5.tgz",
+      "integrity": "sha512-kOLwlcDPnVz2QMhiBv0OQ8le8hTCqKM9cRXlfVPL91l3RGeOsxrIhNRsUt3Xb8wb+pTVUolW+JXKym93vRKxCw==",
       "license": "MIT",
       "funding": {
         "type": "opencollective",
@@ -934,9 +934,9 @@
       }
     },
     "node_modules/@mui/icons-material": {
-      "version": "7.3.4",
-      "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.4.tgz",
-      "integrity": "sha512-9n6Xcq7molXWYb680N2Qx+FRW8oT6j/LXF5PZFH3ph9X/Rct0B/BlLAsFI7iL9ySI6LVLuQIVtrLiPT82R7OZw==",
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.3.5.tgz",
+      "integrity": "sha512-LciL1GLMZ+VlzyHAALSVAR22t8IST4LCXmljcUSx2NOutgO2XnxdIp8ilFbeNf9wpo0iUFbAuoQcB7h+HHIf3A==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.28.4"
@@ -949,7 +949,7 @@
         "url": "https://opencollective.com/mui-org"
       },
       "peerDependencies": {
-        "@mui/material": "^7.3.4",
+        "@mui/material": "^7.3.5",
         "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
         "react": "^17.0.0 || ^18.0.0 || ^19.0.0"
       },
@@ -960,22 +960,22 @@
       }
     },
     "node_modules/@mui/material": {
-      "version": "7.3.4",
-      "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.4.tgz",
-      "integrity": "sha512-gEQL9pbJZZHT7lYJBKQCS723v1MGys2IFc94COXbUIyCTWa+qC77a7hUax4Yjd5ggEm35dk4AyYABpKKWC4MLw==",
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.3.5.tgz",
+      "integrity": "sha512-8VVxFmp1GIm9PpmnQoCoYo0UWHoOrdA57tDL62vkpzEgvb/d71Wsbv4FRg7r1Gyx7PuSo0tflH34cdl/NvfHNQ==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.28.4",
-        "@mui/core-downloads-tracker": "^7.3.4",
-        "@mui/system": "^7.3.3",
-        "@mui/types": "^7.4.7",
-        "@mui/utils": "^7.3.3",
+        "@mui/core-downloads-tracker": "^7.3.5",
+        "@mui/system": "^7.3.5",
+        "@mui/types": "^7.4.8",
+        "@mui/utils": "^7.3.5",
         "@popperjs/core": "^2.11.8",
         "@types/react-transition-group": "^4.4.12",
         "clsx": "^2.1.1",
         "csstype": "^3.1.3",
         "prop-types": "^15.8.1",
-        "react-is": "^19.1.1",
+        "react-is": "^19.2.0",
         "react-transition-group": "^4.4.5"
       },
       "engines": {
@@ -988,7 +988,7 @@
       "peerDependencies": {
         "@emotion/react": "^11.5.0",
         "@emotion/styled": "^11.3.0",
-        "@mui/material-pigment-css": "^7.3.3",
+        "@mui/material-pigment-css": "^7.3.5",
         "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0",
         "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
         "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
@@ -1009,13 +1009,13 @@
       }
     },
     "node_modules/@mui/private-theming": {
-      "version": "7.3.3",
-      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.3.tgz",
-      "integrity": "sha512-OJM+9nj5JIyPUvsZ5ZjaeC9PfktmK+W5YaVLToLR8L0lB/DGmv1gcKE43ssNLSvpoW71Hct0necfade6+kW3zQ==",
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-7.3.5.tgz",
+      "integrity": "sha512-cTx584W2qrLonwhZLbEN7P5pAUu0nZblg8cLBlTrZQ4sIiw8Fbvg7GvuphQaSHxPxrCpa7FDwJKtXdbl2TSmrA==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.28.4",
-        "@mui/utils": "^7.3.3",
+        "@mui/utils": "^7.3.5",
         "prop-types": "^15.8.1"
       },
       "engines": {
@@ -1036,9 +1036,9 @@
       }
     },
     "node_modules/@mui/styled-engine": {
-      "version": "7.3.3",
-      "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.3.tgz",
-      "integrity": "sha512-CmFxvRJIBCEaWdilhXMw/5wFJ1+FT9f3xt+m2pPXhHPeVIbBg9MnMvNSJjdALvnQJMPw8jLhrUtXmN7QAZV2fw==",
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-7.3.5.tgz",
+      "integrity": "sha512-zbsZ0uYYPndFCCPp2+V3RLcAN6+fv4C8pdwRx6OS3BwDkRCN8WBehqks7hWyF3vj1kdQLIWrpdv/5Y0jHRxYXQ==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.28.4",
@@ -1070,16 +1070,16 @@
       }
     },
     "node_modules/@mui/system": {
-      "version": "7.3.3",
-      "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.3.tgz",
-      "integrity": "sha512-Lqq3emZr5IzRLKaHPuMaLBDVaGvxoh6z7HMWd1RPKawBM5uMRaQ4ImsmmgXWtwJdfZux5eugfDhXJUo2mliS8Q==",
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/@mui/system/-/system-7.3.5.tgz",
+      "integrity": "sha512-yPaf5+gY3v80HNkJcPi6WT+r9ebeM4eJzrREXPxMt7pNTV/1eahyODO4fbH3Qvd8irNxDFYn5RQ3idHW55rA6g==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.28.4",
-        "@mui/private-theming": "^7.3.3",
-        "@mui/styled-engine": "^7.3.3",
-        "@mui/types": "^7.4.7",
-        "@mui/utils": "^7.3.3",
+        "@mui/private-theming": "^7.3.5",
+        "@mui/styled-engine": "^7.3.5",
+        "@mui/types": "^7.4.8",
+        "@mui/utils": "^7.3.5",
         "clsx": "^2.1.1",
         "csstype": "^3.1.3",
         "prop-types": "^15.8.1"
@@ -1110,9 +1110,9 @@
       }
     },
     "node_modules/@mui/types": {
-      "version": "7.4.7",
-      "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.7.tgz",
-      "integrity": "sha512-8vVje9rdEr1rY8oIkYgP+Su5Kwl6ik7O3jQ0wl78JGSmiZhRHV+vkjooGdKD8pbtZbutXFVTWQYshu2b3sG9zw==",
+      "version": "7.4.8",
+      "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.4.8.tgz",
+      "integrity": "sha512-ZNXLBjkPV6ftLCmmRCafak3XmSn8YV0tKE/ZOhzKys7TZXUiE0mZxlH8zKDo6j6TTUaDnuij68gIG+0Ucm7Xhw==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.28.4"
@@ -1127,17 +1127,17 @@
       }
     },
     "node_modules/@mui/utils": {
-      "version": "7.3.3",
-      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.3.tgz",
-      "integrity": "sha512-kwNAUh7bLZ7mRz9JZ+6qfRnnxbE4Zuc+RzXnhSpRSxjTlSTj7b4JxRLXpG+MVtPVtqks5k/XC8No1Vs3x4Z2gg==",
+      "version": "7.3.5",
+      "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-7.3.5.tgz",
+      "integrity": "sha512-jisvFsEC3sgjUjcPnR4mYfhzjCDIudttSGSbe1o/IXFNu0kZuR+7vqQI0jg8qtcVZBHWrwTfvAZj9MNMumcq1g==",
       "license": "MIT",
       "dependencies": {
         "@babel/runtime": "^7.28.4",
-        "@mui/types": "^7.4.7",
+        "@mui/types": "^7.4.8",
         "@types/prop-types": "^15.7.15",
         "clsx": "^2.1.1",
         "prop-types": "^15.8.1",
-        "react-is": "^19.1.1"
+        "react-is": "^19.2.0"
       },
       "engines": {
         "node": ">=14.0.0"
@@ -2863,9 +2863,9 @@
       }
     },
     "node_modules/react-router": {
-      "version": "7.9.4",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.4.tgz",
-      "integrity": "sha512-SD3G8HKviFHg9xj7dNODUKDFgpG4xqD5nhyd0mYoB5iISepuZAvzSr8ywxgxKJ52yRzf/HWtVHc9AWwoTbljvA==",
+      "version": "7.9.5",
+      "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.5.tgz",
+      "integrity": "sha512-JmxqrnBZ6E9hWmf02jzNn9Jm3UqyeimyiwzD69NjxGySG6lIz/1LVPsoTCwN7NBX2XjCEa1LIX5EMz1j2b6u6A==",
       "license": "MIT",
       "dependencies": {
         "cookie": "^1.0.1",
@@ -2885,12 +2885,12 @@
       }
     },
     "node_modules/react-router-dom": {
-      "version": "7.9.4",
-      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.4.tgz",
-      "integrity": "sha512-f30P6bIkmYvnHHa5Gcu65deIXoA2+r3Eb6PJIAddvsT9aGlchMatJ51GgpU470aSqRRbFX22T70yQNUGuW3DfA==",
+      "version": "7.9.5",
+      "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.5.tgz",
+      "integrity": "sha512-mkEmq/K8tKN63Ae2M7Xgz3c9l9YNbY+NHH6NNeUmLA3kDkhKXRsNb/ZpxaEunvGo2/3YXdk5EJU3Hxp3ocaBPw==",
       "license": "MIT",
       "dependencies": {
-        "react-router": "7.9.4"
+        "react-router": "7.9.5"
       },
       "engines": {
         "node": ">=20.0.0"
@@ -3067,9 +3067,9 @@
       "license": "MIT"
     },
     "node_modules/set-cookie-parser": {
-      "version": "2.7.1",
-      "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
-      "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+      "version": "2.7.2",
+      "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz",
+      "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==",
       "license": "MIT"
     },
     "node_modules/source-map": {
@@ -3245,9 +3245,9 @@
       }
     },
     "node_modules/vite": {
-      "version": "7.1.12",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.12.tgz",
-      "integrity": "sha512-ZWyE8YXEXqJrrSLvYgrRP7p62OziLW7xI5HYGWFzOvupfAlrLvURSzv/FyGyy0eidogEM3ujU+kUG1zuHgb6Ug==",
+      "version": "7.2.2",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.2.tgz",
+      "integrity": "sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
diff --git a/cmd/kueueviz/frontend/package.json b/cmd/kueueviz/frontend/package.json
index c575317fa..50f90e39f 100644
--- a/cmd/kueueviz/frontend/package.json
+++ b/cmd/kueueviz/frontend/package.json
@@ -15,19 +15,19 @@
   "dependencies": {
     "@emotion/react": "^11.14.0",
     "@emotion/styled": "^11.14.1",
-    "@mui/icons-material": "^7.3.4",
+    "@mui/icons-material": "^7.3.5",
     "@mui/material": "^7.3.1",
     "ace-builds": "^1.43.4",
     "react": "^19.2.0",
     "react-ace": "^14.0.1",
     "react-dom": "^19.2.0",
-    "react-router-dom": "^7.9.4",
+    "react-router-dom": "^7.9.5",
     "react-toastify": "^11.0.5"
   },
   "devDependencies": {
     "@vitejs/plugin-react": "^5.1.0",
     "depcheck": "^1.4.7",
-    "vite": "^7.1.12"
+    "vite": "^7.2.2"
   },
   "browserslist": {
     "production": [
diff --git a/config/components/crd/bases/kueue.x-k8s.io_workloads.yaml b/config/components/crd/bases/kueue.x-k8s.io_workloads.yaml
index cd6912590..5dfd7860f 100644
--- a/config/components/crd/bases/kueue.x-k8s.io_workloads.yaml
+++ b/config/components/crd/bases/kueue.x-k8s.io_workloads.yaml
@@ -18108,35 +18108,57 @@ spec:
                 description: |-
                   priority determines the order of access to the resources managed by the
                   ClusterQueue where the workload is queued.
-                  The priority value is populated from PriorityClassName.
+                  The priority value is populated from the referenced PriorityClass (via priorityClassRef).
                   The higher the value, the higher the priority.
-                  If priorityClassName is specified, priority must not be null.
+                  If priorityClassRef is specified, priority must not be null.
                 format: int32
                 type: integer
-              priorityClassName:
-                description: |-
-                  priorityClassName is the name of the PriorityClass the Workload is associated with.
-                  If specified, indicates the workload's priority.
-                  "system-node-critical" and "system-cluster-critical" are two special
-                  keywords which indicate the highest priorities with the former being
-                  the highest priority. Any other name must be defined by creating a
-                  PriorityClass object with that name. If not specified, the workload
-                  priority will be default or zero if there is no default.
-                maxLength: 253
-                minLength: 1
-                pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
-                type: string
-              priorityClassSource:
-                default: ""
-                description: |-
-                  priorityClassSource determines whether the priorityClass field refers to a pod PriorityClass or kueue.x-k8s.io/workloadpriorityclass.
-                  Workload's PriorityClass can accept the name of a pod priorityClass or a workloadPriorityClass.
-                  When using pod PriorityClass, a priorityClassSource field has the scheduling.k8s.io/priorityclass value.
-                enum:
-                - kueue.x-k8s.io/workloadpriorityclass
-                - scheduling.k8s.io/priorityclass
-                - ""
-                type: string
+              priorityClassRef:
+                description: priorityClassRef references a PriorityClass object that
+                  defines the workload's priority.
+                properties:
+                  group:
+                    description: |-
+                      group is the API group of the PriorityClass object.
+                      Use "kueue.x-k8s.io" for WorkloadPriorityClass.
+                      Use "scheduling.k8s.io" for Pod PriorityClass.
+                    enum:
+                    - kueue.x-k8s.io
+                    - scheduling.k8s.io
+                    type: string
+                  kind:
+                    description: kind is the kind of the PriorityClass object.
+                    enum:
+                    - WorkloadPriorityClass
+                    - PriorityClass
+                    type: string
+                  name:
+                    description: |-
+                      name is the name of the PriorityClass the Workload is associated with.
+                      If specified, indicates the workload's priority.
+                      "system-node-critical" and "system-cluster-critical" are two special
+                      keywords which indicate the highest priorities with the former being
+                      the highest priority. Any other name must be defined by creating a
+                      PriorityClass object with that name. If not specified, the workload
+                      priority will be default or zero if there is no default.
+                    maxLength: 253
+                    minLength: 1
+                    pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
+                    type: string
+                required:
+                - group
+                - kind
+                - name
+                type: object
+                x-kubernetes-validations:
+                - message: only the PriorityClass kind is allowed for the scheduling.k8s.io
+                    group
+                  rule: '(self.group == ''scheduling.k8s.io'') ? self.kind == ''PriorityClass''
+                    : true'
+                - message: only the WorkloadPriorityClass kind is allowed for the
+                    kueue.x-k8s.io group
+                  rule: '(self.group == ''kueue.x-k8s.io'') ? self.kind == ''WorkloadPriorityClass''
+                    : true'
               queueName:
                 description: |-
                   queueName is the name of the LocalQueue the Workload is associated with.
@@ -18146,8 +18168,8 @@ spec:
                 type: string
             type: object
             x-kubernetes-validations:
-            - message: priority should not be nil when priorityClassName is set
-              rule: 'has(self.priorityClassName) ? has(self.priority) : true'
+            - message: priority should not be nil when priorityClassRef is set
+              rule: '!has(self.priorityClassRef) || has(self.priority)'
           status:
             description: status is the status of the Workload.
             properties:
@@ -18191,6 +18213,9 @@ spec:
                             Kueue schedules the second pass of scheduling for each workload with at
                             least one PodSet which has delayedTopologyRequest=true and without
                             topologyAssignment.
+                          enum:
+                          - Pending
+                          - Ready
                           maxLength: 7
                           type: string
                         flavors:
@@ -18716,22 +18741,29 @@ spec:
             c.type == ''QuotaReserved'' && c.status == ''True'') && has(self.status.admission)
             ? size(self.spec.podSets) == size(self.status.admission.podSetAssignments)
             : true'
-        - message: priorityClassSource is immutable while workload quota reserved
+        - message: priorityClassRef is immutable while workload quota reserved
           rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c,
-            c.type == ''QuotaReserved'' && c.status == ''True'')) ? ((!has(self.spec.priorityClassSource)
-            && !has(oldSelf.spec.priorityClassSource)) || (has(self.spec.priorityClassSource)
-            && has(oldSelf.spec.priorityClassSource) && self.spec.priorityClassSource
-            == oldSelf.spec.priorityClassSource) || (!has(self.spec.priorityClassSource)
-            && has(oldSelf.spec.priorityClassSource) && oldSelf.spec.priorityClassSource.size()
-            == 0) || (!has(oldSelf.spec.priorityClassSource) && has(self.spec.priorityClassSource)
-            && self.spec.priorityClassSource.size() == 0)) : true'
-        - message: priorityClassName is immutable while workload quota reserved and
-            priorityClassSource is not equal to kueue.x-k8s.io/workloadpriorityclass
+            c.type == ''QuotaReserved'' && c.status == ''True'')) ? (!has(oldSelf.spec.priorityClassRef)
+            && !has(self.spec.priorityClassRef)) || (has(oldSelf.spec.priorityClassRef)
+            && has(self.spec.priorityClassRef)) : true'
+        - message: priorityClassRef.group is immutable while workload quota reserved
           rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c,
-            c.type == ''QuotaReserved'' && c.status == ''True'') && (self.spec.priorityClassSource
-            != ''kueue.x-k8s.io/workloadpriorityclass'') && has(oldSelf.spec.priorityClassName)
-            && has(self.spec.priorityClassName)) ? (oldSelf.spec.priorityClassName
-            == self.spec.priorityClassName) : true'
+            c.type == ''QuotaReserved'' && c.status == ''True'') && has(oldSelf.spec.priorityClassRef)
+            && has(self.spec.priorityClassRef)) ? oldSelf.spec.priorityClassRef.group
+            == self.spec.priorityClassRef.group : true'
+        - message: priorityClassRef.kind is immutable while workload quota reserved
+          rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c,
+            c.type == ''QuotaReserved'' && c.status == ''True'') && has(oldSelf.spec.priorityClassRef)
+            && has(self.spec.priorityClassRef)) ? oldSelf.spec.priorityClassRef.kind
+            == self.spec.priorityClassRef.kind : true'
+        - message: priorityClassRef.name is immutable for scheduling.k8s.io/priorityclass
+            while workload quota reserved
+          rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c,
+            c.type == ''QuotaReserved'' && c.status == ''True'') && has(oldSelf.spec.priorityClassRef)
+            && has(self.spec.priorityClassRef) && self.spec.priorityClassRef.group
+            == ''scheduling.k8s.io'' && self.spec.priorityClassRef.kind == ''PriorityClass'')
+            ? oldSelf.spec.priorityClassRef.name == self.spec.priorityClassRef.name
+            : true'
         - message: queueName is immutable while workload quota reserved
           rule: '(has(oldSelf.status) && has(oldSelf.status.conditions) && oldSelf.status.conditions.exists(c,
             c.type == ''QuotaReserved'' && c.status == ''True'')) && (has(self.status)
diff --git a/go.mod b/go.mod
index cc6d47e30..7a4e879bc 100644
--- a/go.mod
+++ b/go.mod
@@ -8,22 +8,22 @@ require (
 	github.com/go-logr/logr v1.4.3
 	github.com/google/go-cmp v0.7.0
 	github.com/json-iterator/go v1.1.12
-	github.com/kubeflow/mpi-operator v0.6.0
-	github.com/kubeflow/trainer/v2 v2.1.0-rc.0
+	github.com/kubeflow/mpi-operator v0.7.0
+	github.com/kubeflow/trainer/v2 v2.1.0
 	github.com/kubeflow/training-operator v1.9.3
-	github.com/onsi/ginkgo/v2 v2.27.1
+	github.com/onsi/ginkgo/v2 v2.27.2
 	github.com/onsi/gomega v1.38.2
 	github.com/open-policy-agent/cert-controller v0.14.0
 	github.com/project-codeflare/appwrapper v1.1.2
 	github.com/prometheus/client_golang v1.23.2
 	github.com/prometheus/client_model v0.6.2
-	github.com/ray-project/kuberay/ray-operator v1.4.2
+	github.com/ray-project/kuberay/ray-operator v1.5.0
 	github.com/spf13/cobra v1.10.1
 	github.com/spf13/pflag v1.0.10
 	go.uber.org/mock v0.6.0
 	go.uber.org/zap v1.27.0
 	golang.org/x/exp v0.0.0-20250718183923-645b1fa84792
-	golang.org/x/sync v0.17.0
+	golang.org/x/sync v0.18.0
 	k8s.io/api v0.34.1
 	k8s.io/apimachinery v0.34.1
 	k8s.io/apiserver v0.34.1
@@ -36,8 +36,8 @@ require (
 	k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912
 	k8s.io/kubectl v0.34.1
 	k8s.io/metrics v0.34.1
-	k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
-	sigs.k8s.io/controller-runtime v0.22.3
+	k8s.io/utils v0.0.0-20251002143259-bc988d571ff4
+	sigs.k8s.io/controller-runtime v0.22.4
 	sigs.k8s.io/jobset v0.10.1
 	sigs.k8s.io/lws v0.7.0
 	sigs.k8s.io/structured-merge-diff/v6 v6.3.0
@@ -122,19 +122,18 @@ require (
 	go.opentelemetry.io/otel/trace v1.37.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.7.0 // indirect
 	go.uber.org/atomic v1.11.0 // indirect
-	go.uber.org/automaxprocs v1.6.0 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
-	go.yaml.in/yaml/v2 v2.4.2 // indirect
+	go.yaml.in/yaml/v2 v2.4.3 // indirect
 	go.yaml.in/yaml/v3 v3.0.4 // indirect
-	golang.org/x/crypto v0.42.0 // indirect
-	golang.org/x/mod v0.27.0 // indirect
-	golang.org/x/net v0.44.0 // indirect
+	golang.org/x/crypto v0.43.0 // indirect
+	golang.org/x/mod v0.29.0 // indirect
+	golang.org/x/net v0.46.0 // indirect
 	golang.org/x/oauth2 v0.31.0 // indirect
-	golang.org/x/sys v0.36.0 // indirect
-	golang.org/x/term v0.35.0 // indirect
-	golang.org/x/text v0.29.0 // indirect
-	golang.org/x/time v0.13.0 // indirect
-	golang.org/x/tools v0.36.0 // indirect
+	golang.org/x/sys v0.37.0 // indirect
+	golang.org/x/term v0.36.0 // indirect
+	golang.org/x/text v0.30.0 // indirect
+	golang.org/x/time v0.14.0 // indirect
+	golang.org/x/tools v0.38.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.5.0 // indirect
 	google.golang.org/genproto/googleapis/api v0.0.0-20250721164621-a45f3dfb1074 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20250929231259-57b25ae835d4 // indirect
@@ -154,6 +153,6 @@ require (
 	sigs.k8s.io/kustomize/api v0.20.1 // indirect
 	sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect
 	sigs.k8s.io/randfill v1.0.0 // indirect
-	sigs.k8s.io/scheduler-plugins v0.31.8 // indirect
-	volcano.sh/apis v1.12.2 // indirect
+	sigs.k8s.io/scheduler-plugins v0.34.1-devel // indirect
+	volcano.sh/apis v1.13.1-0.20251028070205-46d20c0699e7 // indirect
 )
diff --git a/go.sum b/go.sum
index 196bc9055..67e0a63ec 100644
--- a/go.sum
+++ b/go.sum
@@ -134,10 +134,10 @@ 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=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/kubeflow/mpi-operator v0.6.0 h1:RzzG03oyQIiHe/SH2k19N+Hp4QkxEsG2l9G1T7US+ys=
-github.com/kubeflow/mpi-operator v0.6.0/go.mod h1:lu3cj3ESq3SdS29nbHC26TuXiTYYQYTHJ6fcy5Xv20c=
-github.com/kubeflow/trainer/v2 v2.1.0-rc.0 h1:kr4Gjb7osBIwZm5qE4ajwxe0P4n2lWwD3grhfXc66ds=
-github.com/kubeflow/trainer/v2 v2.1.0-rc.0/go.mod h1:Y9hmSGG3A9tFKUjlcWf7Kg/SwibYwrZTK5ZqAxMxyno=
+github.com/kubeflow/mpi-operator v0.7.0 h1:ID1eyzAFOMofgynEvfy4//S3q7Ra1OSexrggb1VcC1o=
+github.com/kubeflow/mpi-operator v0.7.0/go.mod h1:F6RbTC2l6Q7zrpCUA++sickyWWj32K/pk5WJhZnKS/c=
+github.com/kubeflow/trainer/v2 v2.1.0 h1:jRABD9ZYToamNH2atHze3L/VC/v6KCAqUEqsOQOjVTg=
+github.com/kubeflow/trainer/v2 v2.1.0/go.mod h1:AgnSIoJi4J2LEiywx1g43/8rOpM49hpD8KA3LTQzl0M=
 github.com/kubeflow/training-operator v1.9.3 h1:aaSHqskOtCY8Dn8sVd+l9p5XAczW6O0nYMPjVLAw/lc=
 github.com/kubeflow/training-operator v1.9.3/go.mod h1:6zI0hgeCOheiW5Z12IcVkKBuSWm714fz8mUvYu4Fid4=
 github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
@@ -168,8 +168,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
 github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
-github.com/onsi/ginkgo/v2 v2.27.1 h1:0LJC8MpUSQnfnp4n/3W3GdlmJP3ENGF0ZPzjQGLPP7s=
-github.com/onsi/ginkgo/v2 v2.27.1/go.mod h1:wmy3vCqiBjirARfVhAqFpYt8uvX0yaFe+GudAqqcCqA=
+github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
+github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
 github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
 github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
 github.com/open-policy-agent/cert-controller v0.14.0 h1:TPc19BOHOs4tARruTT5o4bzir7Ed6FF+j3EXP/nmZBs=
@@ -185,8 +185,6 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
-github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
 github.com/project-codeflare/appwrapper v1.1.2 h1:iEEyYGSDXOxMXc/AZEvTDDXy1DNi+cWUQ93uM6XAXJc=
 github.com/project-codeflare/appwrapper v1.1.2/go.mod h1:+Pfxe92YSxrFqO1ovRZTQ1PRrQqkdq5fLCxn1Ok6ZlQ=
 github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
@@ -197,10 +195,10 @@ github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9Z
 github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
 github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
 github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
-github.com/ray-project/kuberay/ray-operator v1.4.2 h1:A4tGzbIky8sInAUxZBdBb+rrpZ7fbqoxdsOtm559Zqg=
-github.com/ray-project/kuberay/ray-operator v1.4.2/go.mod h1:oZaK6ZxZS57/JYvCbJdU1FdIMPW1JJNv6TqbAcUjE/8=
-github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
-github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/ray-project/kuberay/ray-operator v1.5.0 h1:KCjCQ7PSsvs9Ke+90CZbbs498nuaIJ/JkXk4vd54EVg=
+github.com/ray-project/kuberay/ray-operator v1.5.0/go.mod h1:itUPJnr3QwoZT70gRgsWFpBolquuZtDRCkdA1lrAb7Y=
+github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
+github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
@@ -285,8 +283,6 @@ go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz
 go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
 go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
 go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
-go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
-go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
@@ -295,55 +291,55 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
 go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
 go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
-go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
-go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
+go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
+go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
 go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
 go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
-golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
+golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
+golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
 golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4=
 golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
-golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
+golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
+golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
-golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
+golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
+golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
 golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo=
 golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
-golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
+golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
-golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
-golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
-golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
+golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
+golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q=
+golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
-golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
-golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=
-golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
+golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
+golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
+golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
+golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
-golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
+golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
+golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
 golang.org/x/tools/go/expect v0.1.1-deprecated h1:jpBZDwmgPhXsKZC6WhL20P4b/wmnpsEAGHaNy0n/rJM=
 golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
 golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM=
@@ -410,12 +406,12 @@ k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI=
 k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A=
 k8s.io/metrics v0.34.1 h1:374Rexmp1xxgRt64Bi0TsjAM8cA/Y8skwCoPdjtIslE=
 k8s.io/metrics v0.34.1/go.mod h1:Drf5kPfk2NJrlpcNdSiAAHn/7Y9KqxpRNagByM7Ei80=
-k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0=
-k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
+k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0 h1:qPrZsv1cwQiFeieFlRqT627fVZ+tyfou/+S5S0H5ua0=
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.33.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
-sigs.k8s.io/controller-runtime v0.22.3 h1:I7mfqz/a/WdmDCEnXmSPm8/b/yRTy6JsKKENTijTq8Y=
-sigs.k8s.io/controller-runtime v0.22.3/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8=
+sigs.k8s.io/controller-runtime v0.22.4 h1:GEjV7KV3TY8e+tJ2LCTxUTanW4z/FmNB7l327UfMq9A=
+sigs.k8s.io/controller-runtime v0.22.4/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8=
 sigs.k8s.io/gateway-api v1.4.0 h1:ZwlNM6zOHq0h3WUX2gfByPs2yAEsy/EenYJB78jpQfQ=
 sigs.k8s.io/gateway-api v1.4.0/go.mod h1:AR5RSqciWP98OPckEjOjh2XJhAe2Na4LHyXD2FUY7Qk=
 sigs.k8s.io/jobset v0.10.1 h1:u8QKifNsrWVrlRFe6w2ofYTqFT9ma2DRHxfeB2m9xyU=
@@ -430,11 +426,11 @@ sigs.k8s.io/lws v0.7.0 h1:qWfzX8+UBak+Hq0+m/PuE3uO0mp/3dmm5q/h/7z31A8=
 sigs.k8s.io/lws v0.7.0/go.mod h1:WLg0CkyJTRQWMUOUam6qi9qRmcj3LAIWQUT81d4BGr4=
 sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
 sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
-sigs.k8s.io/scheduler-plugins v0.31.8 h1:Ie2EFRnkE9T2tBjxwypww7hJJyPRIwrXJNZeNxjP6QY=
-sigs.k8s.io/scheduler-plugins v0.31.8/go.mod h1:KkcXEbf9CYaoZ5ntbAMSYmquPq9MtSfXVpI31R6mHeM=
+sigs.k8s.io/scheduler-plugins v0.34.1-devel h1:tT0/rFgjM7+VVDTKkcjA/XxhpYgRyq+RV0P7QW1Pxvo=
+sigs.k8s.io/scheduler-plugins v0.34.1-devel/go.mod h1:YQJimEVm3dpz9va/BlzgsK1HQ3KGIehABDz+D5PPP50=
 sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
 sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
 sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
 sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
-volcano.sh/apis v1.12.2 h1:KvNyM/kMizFVlALiH/uFHPwYFHRtxuVnBL0upbFbDss=
-volcano.sh/apis v1.12.2/go.mod h1:0XNNnIOevJSYNiXRmwhXUrYCcCcWcBeTY0nxrlkk03A=
+volcano.sh/apis v1.13.1-0.20251028070205-46d20c0699e7 h1:uRQSF3S3+nsi1IcE0brZBwzqzh6Ne8Gz3SHyBcCENRA=
+volcano.sh/apis v1.13.1-0.20251028070205-46d20c0699e7/go.mod h1:CKQbxVt0o4lTKisC0MonoXWruGFC0S8KU+UuzaZ5E7k=
diff --git a/hack/cypress/Dockerfile b/hack/cypress/Dockerfile
index 840a69575..a74a44def 100644
--- a/hack/cypress/Dockerfile
+++ b/hack/cypress/Dockerfile
@@ -1 +1 @@
-FROM cypress/base:22.21.0
+FROM cypress/base:24.11.0
diff --git a/hack/internal/tools/go.mod b/hack/internal/tools/go.mod
index c9289d1dc..80852c90d 100644
--- a/hack/internal/tools/go.mod
+++ b/hack/internal/tools/go.mod
@@ -164,7 +164,7 @@ require (
 	github.com/clbanning/mxj/v2 v2.7.0 // indirect
 	github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 // indirect
 	github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be // indirect
-	github.com/containerd/containerd v1.7.28 // indirect
+	github.com/containerd/containerd v1.7.29 // indirect
 	github.com/containerd/errdefs v0.3.0 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
diff --git a/hack/internal/tools/go.sum b/hack/internal/tools/go.sum
index 445ff09bd..25c83e908 100644
--- a/hack/internal/tools/go.sum
+++ b/hack/internal/tools/go.sum
@@ -324,8 +324,8 @@ github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv
 github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
 github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ=
 github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w=
-github.com/containerd/containerd v1.7.28 h1:Nsgm1AtcmEh4AHAJ4gGlNSaKgXiNccU270Dnf81FQ3c=
-github.com/containerd/containerd v1.7.28/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
+github.com/containerd/containerd v1.7.29 h1:90fWABQsaN9mJhGkoVnuzEY+o1XDPbg9BTC9QTAHnuE=
+github.com/containerd/containerd v1.7.29/go.mod h1:azUkWcOvHrWvaiUjSQH0fjzuHIwSPg1WL5PshGP4Szs=
 github.com/containerd/errdefs v0.3.0 h1:FSZgGOeK4yuT/+DnF07/Olde/q4KBoMsaamhXxIMDp4=
 github.com/containerd/errdefs v0.3.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
 github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
diff --git a/hack/multikueue/manager-cluster.kind.yaml b/hack/multikueue/manager-cluster.kind.yaml
index 8962e9364..7c4f0cedb 100644
--- a/hack/multikueue/manager-cluster.kind.yaml
+++ b/hack/multikueue/manager-cluster.kind.yaml
@@ -24,6 +24,7 @@ nodes:
 - role: worker
   labels:
     instance-type: on-demand
+    cloud.provider.com/node-group: tas-node
 
 kubeadmConfigPatches:
   - |
diff --git a/hack/multikueue/worker-cluster.kind.yaml b/hack/multikueue/worker-cluster.kind.yaml
index 8962e9364..7c4f0cedb 100644
--- a/hack/multikueue/worker-cluster.kind.yaml
+++ b/hack/multikueue/worker-cluster.kind.yaml
@@ -24,6 +24,7 @@ nodes:
 - role: worker
   labels:
     instance-type: on-demand
+    cloud.provider.com/node-group: tas-node
 
 kubeadmConfigPatches:
   - |
diff --git a/keps/2724-topology-aware-scheduling/README.md b/keps/2724-topology-aware-scheduling/README.md
index 421c93cf7..d8baa1d23 100644
--- a/keps/2724-topology-aware-scheduling/README.md
+++ b/keps/2724-topology-aware-scheduling/README.md
@@ -46,6 +46,8 @@
   - [Cross-PodSet Topology Aware scheduling](#cross-podset-topology-aware-scheduling)
     - [Ensure leader and workers end up on the same flavor](#ensure-leader-and-workers-end-up-on-the-same-flavor)
   - [Enforcing the assignment](#enforcing-the-assignment)
+  - [Balanced placement](#balanced-placement)
+    - [Example](#example-2)
   - [Support for ProvisioningRequests](#support-for-provisioningrequests)
     - [Determining the need for second pass](#determining-the-need-for-second-pass)
     - [Targeting the newly provisioned nodes](#targeting-the-newly-provisioned-nodes)
@@ -69,7 +71,7 @@
     - [Rename the topologyAssignment.domains.values field as levelValues](#rename-the-topologyassignmentdomainsvalues-field-as-levelvalues)
   - [Drop dedicated TAS label](#drop-dedicated-tas-label)
   - [MostFreeCapacity algorithm](#mostfreecapacity-algorithm)
-    - [Example](#example-2)
+    - [Example](#example-3)
 <!-- /toc -->
 
 ## Summary
@@ -1038,6 +1040,10 @@ Kueue places pods on domains with different algorithms, depending on the annotat
 - `LeastFreeCapacity` algorithm - Kueue selects as many domains as needed (if it meets user's requirement) starting from the one with the least free capacity;
 - `BestFit` algorithm - Kueue selects as many domains as needed (if it meets user's requirement) starting from the one with the most free capacity.
 However, it optimizes the selection of the last domain at each level to minimize the remaining free resources.
+- `BalancedPlacement` algorithm - Kueue selects as many domains as needed (if it meets user's requirement)
+and places pods evenly on the selected domains. The balanced placement is performed only at two consecutive
+levels, where the higher of these two levels is indicated by the `preferred` annotation
+(for more details see [Balanced placement](#balanced-placement)).
 
 #### Example
 Consider a rack with four nodes that can accommodate 3, 3, 2, and 1 pod, respectively. A PodSet consists of 7 pods.
@@ -1075,6 +1081,7 @@ Since v0.15, the available feature gates are as follows:
 | None <br/> or TASProfileMixed (default)    | BestFit           | BestFit           | LeastFreeCapacity |
 | TASProfileBestFit (deprecated)             | BestFit           | BestFit           | BestFit           |
 | TASProfileLeastFreeCapacity (deprecated)   | LeastFreeCapacity | LeastFreeCapacity | LeastFreeCapacity |
+| TASBalancedPlacement                       | BalancedPlacement | BestFit           | LeastFreeCapacity |
 
 Based on the user feedback, we decided to make `TASProfileMixed` default starting in v0.15. (The corresponding feature gate is hence obsolete; we formally keep it "deprecated" for backwards compatibility). It differs from the previous default only in the `unconstrained` case - in which Kueue should prioritize minimizing fragmentation which is provided by the `LeastFreeCapacity` algorithm.
 
@@ -1173,6 +1180,62 @@ to ungate a Pod. The expectation is fulfilled if the Pod is observed as ungated
 or the ungating request fails. We hold ungating if there are pending ungatings
 within the PodSet.
 
+### Balanced placement
+The balanced placement algorithm provides an alternative to the greedy packing strategies. Instead of iterating over the domains sorted from largest to smallest available space (or based on some other criteria) and trying to pack as many pods as possible to each domain until the request fits, it first finds the optimal set of domains that fit the request and then distributes the pods as evenly as possible across these domains. 
+
+Greedy placement strategies (such as `BestFit` and `LeastFreeCapacity`) might result in a placement with a small
+number of pods assigned to the last considered domain (even though the existing algorithms choose the best possible
+last domain). For example 12 pods distributed among domains with capacities (10,10) will be placed (10,2). However,
+in some applications, a more balanced placement (6,6) would be more efficient. Some examples of such cases would be
+all-to-all communication procedures (e.g. Allgather) since more balanced placement leads to more efficient
+cross-domain traffic.
+
+In the first implemetation, we propose to perform the balanced algorithm only on two consequtive levels indicated
+by the user with the `preferred` flag. Let L be the level indicated by the `preferred` flag. We assume that the
+request must fit within a single domain on level L-1 and otherwise we fallback to the standard algorithm. The above
+assumptions are motivated by the application of the balanced placement algorithm to all-to-all communication
+on the specific networking for GPUs. If the concept of balanced placement would be useful in other contexts it
+would be possible to lift these assumptions. This balancing algorithm is enabled by the `TASBalancedPlacement` feature gate.
+
+The algorithm could be summarized as follows:
+
+```
+1. For each domain on level L-1:
+   - check if the entire request fits on this domain
+   - calculate T, the maximum possible minimum number of pods that would be placed on a domain on level L+1 if the request is placed on this domain.
+2. If no domain on level L-1 fits the entire request, fallback to the standard algorithm.
+3. Otherwise, pick a domain D on level L-1 that 
+   - first maximizes the value of T
+   - secondly minimizes the number of domains that need to be used on level L to fit the request 
+4. Prune every descendant of D with capacity below T.
+5. On level L find an optimal subset of children of D that fit the request:
+   - first minimize the size of the subset
+   - secondly minimize the total capacity of the subset
+   - thirdly maximize entropies of children capacities of the subset
+6. On level L+1 find an optimal subset of children of domains from step 5 that fit the request:
+   - first minimize the size of the subset
+   - secondly minimize the total capacity of the subset
+7. For the subset found in step 6, place the pods by first placing T pods on each domain, and then distribute the rest abritrarily.
+```
+
+The balancing algorithm will support all the job types currently supported by TAS including:
+
+ - JobSet. Instead of assigning pods, the balancing algorithm will assign slices.
+ - LeaderWorkerSet. Will co-locate leader with workers while keeping the overall
+ assignment per node balanced.
+
+#### Example
+For a 3-level topology (block, rack, hostname), in the TopologyRequest, the user specifies `preferred = rack`. Then the balanced placement will find the following assignments:
+
+| Capacities |Request | SliceSize | Assignment | Comment|
+| --- | --- | --- | ----------- | --- |
+| [[15], [15]] | 25| 1 | [[13], [12]] |
+| [[15, 13, 10]] | 23| 1 | [[12, 11, 0]] |
+| [[20, 10], [15, 15]] | 22| 1 | [[0, 0], [11, 11]] | prefer rack that leads to higher value of T
+| [[20, 10], [15, 15]] | 20| 1 | [[20, 0], [0, 0]] |
+| [[10, 5], [5, 5, 5]] | 15|1 |  [[0, 0], [5, 5, 5]] | prefer more balanced rack
+| [[15],[15]] [[15, 15]] | 25 | 1 | [[0],[0]] [[13, 12]] | prefer block where the request fits in a single rack
+| [[15], [15], [15, 15]] | 25|5 |  [[0], [0], [15, 10]] | `podset-slice-required-topology = hostname`
 ### Support for ProvisioningRequests
 
 We are going to support autoscaling via ProvisioningRequest AdmissionCheck.
diff --git a/keps/2724-topology-aware-scheduling/kep.yaml b/keps/2724-topology-aware-scheduling/kep.yaml
index 18db54904..b06fa80b4 100644
--- a/keps/2724-topology-aware-scheduling/kep.yaml
+++ b/keps/2724-topology-aware-scheduling/kep.yaml
@@ -42,6 +42,7 @@ feature-gates:
   - name: TASFailedNodeReplacement
   - name: TASFailedNodeReplacementFailFast
   - name: TASReplaceNodeOnPodTermination
+  - name: TASBalancedPlacement
 disable-supported: true
 
 # The following PRR answers are required at beta release
diff --git a/pkg/cache/queue/cluster_queue.go b/pkg/cache/queue/cluster_queue.go
index 48ce5e128..4eb0ac459 100644
--- a/pkg/cache/queue/cluster_queue.go
+++ b/pkg/cache/queue/cluster_queue.go
@@ -336,16 +336,22 @@ func (c *ClusterQueue) QueueInadmissibleWorkloads(ctx context.Context, client cl
 	return moved
 }
 
-// Pending returns the total number of pending workloads.
-func (c *ClusterQueue) Pending() int {
+// PendingTotal returns the total number of pending workloads.
+func (c *ClusterQueue) PendingTotal() int {
+	active, inadmissible := c.Pending()
+	return active + inadmissible
+}
+
+// Pending returns the number of active and inadmissible pending workloads.
+func (c *ClusterQueue) Pending() (int, int) {
 	c.rwm.RLock()
 	defer c.rwm.RUnlock()
-	return c.PendingActive() + c.PendingInadmissible()
+	return c.pendingActive(), c.pendingInadmissible()
 }
 
-// PendingActive returns the number of active pending workloads,
+// pendingActive returns the number of active pending workloads,
 // workloads that are in the admission queue.
-func (c *ClusterQueue) PendingActive() int {
+func (c *ClusterQueue) pendingActive() int {
 	result := c.heap.Len()
 	if c.inflight != nil {
 		result++
@@ -353,13 +359,48 @@ func (c *ClusterQueue) PendingActive() int {
 	return result
 }
 
-// PendingInadmissible returns the number of inadmissible pending workloads,
+// pendingInadmissible returns the number of inadmissible pending workloads,
 // workloads that were already tried and are waiting for cluster conditions
 // to change to potentially become admissible.
-func (c *ClusterQueue) PendingInadmissible() int {
+func (c *ClusterQueue) pendingInadmissible() int {
 	return len(c.inadmissibleWorkloads)
 }
 
+// PendingInLocalQueue returns the number of active and inadmissible pending workloads in LocalQueue.
+func (c *ClusterQueue) PendingInLocalQueue(lqRef utilqueue.LocalQueueReference) (int, int) {
+	c.rwm.RLock()
+	defer c.rwm.RUnlock()
+	return c.pendingActiveInLocalQueue(lqRef), c.pendingInadmissibleInLocalQueue(lqRef)
+}
+
+// pendingActiveInLocalQueue returns the number of active pending workloads in LocalQueue,
+// workloads that are in the admission queue.
+func (c *ClusterQueue) pendingActiveInLocalQueue(lqRef utilqueue.LocalQueueReference) (active int) {
+	for _, wl := range c.heap.List() {
+		wlLqKey := utilqueue.KeyFromWorkload(wl.Obj)
+		if wlLqKey == lqRef {
+			active++
+		}
+	}
+	if c.inflight != nil && string(workloadKey(c.inflight)) == string(lqRef) {
+		active++
+	}
+	return
+}
+
+// pendingInadmissibleInLocalQueue returns the number of inadmissible pending workloads in LocalQueue,
+// workloads that were already tried and are waiting for cluster conditions
+// to change to potentially become admissible.
+func (c *ClusterQueue) pendingInadmissibleInLocalQueue(lqRef utilqueue.LocalQueueReference) (inadmissible int) {
+	for _, wl := range c.inadmissibleWorkloads {
+		wlLqKey := utilqueue.KeyFromWorkload(wl.Obj)
+		if wlLqKey == lqRef {
+			inadmissible++
+		}
+	}
+	return
+}
+
 // Pop removes the head of the queue and returns it. It returns nil if the
 // queue is empty.
 func (c *ClusterQueue) Pop() *workload.Info {
diff --git a/pkg/cache/queue/local_queue.go b/pkg/cache/queue/local_queue.go
index 9ce484133..20195db42 100644
--- a/pkg/cache/queue/local_queue.go
+++ b/pkg/cache/queue/local_queue.go
@@ -47,36 +47,3 @@ func (q *LocalQueue) AddOrUpdate(info *workload.Info) {
 	key := workload.Key(info.Obj)
 	q.items[key] = info
 }
-
-func (m *Manager) PendingActiveInLocalQueue(lq *LocalQueue) int {
-	c, ok := m.getClusterQueueLockless(lq.ClusterQueue)
-	result := 0
-	if !ok {
-		return 0
-	}
-	for _, wl := range c.heap.List() {
-		wlLqKey := queue.KeyFromWorkload(wl.Obj)
-		if wlLqKey == lq.Key {
-			result++
-		}
-	}
-	if c.inflight != nil && string(workloadKey(c.inflight)) == string(lq.Key) {
-		result++
-	}
-	return result
-}
-
-func (m *Manager) PendingInadmissibleInLocalQueue(lq *LocalQueue) int {
-	c, ok := m.getClusterQueueLockless(lq.ClusterQueue)
-	if !ok {
-		return 0
-	}
-	result := 0
-	for _, wl := range c.inadmissibleWorkloads {
-		wlLqKey := queue.KeyFromWorkload(wl.Obj)
-		if wlLqKey == lq.Key {
-			result++
-		}
-	}
-	return result
-}
diff --git a/pkg/cache/queue/manager.go b/pkg/cache/queue/manager.go
index 42adebef7..d3832a12e 100644
--- a/pkg/cache/queue/manager.go
+++ b/pkg/cache/queue/manager.go
@@ -406,7 +406,7 @@ func (m *Manager) Pending(cq *kueue.ClusterQueue) (int, error) {
 		return 0, ErrClusterQueueDoesNotExist
 	}
 
-	return cqImpl.Pending(), nil
+	return cqImpl.PendingTotal(), nil
 }
 
 func (m *Manager) QueueForWorkloadExists(wl *kueue.Workload) bool {
@@ -694,8 +694,10 @@ func (m *Manager) Broadcast() {
 }
 
 func (m *Manager) reportLQPendingWorkloads(lq *LocalQueue) {
-	active := m.PendingActiveInLocalQueue(lq)
-	inadmissible := m.PendingInadmissibleInLocalQueue(lq)
+	var active, inadmissible int
+	if cq := m.getClusterQueueLockless(lq.ClusterQueue); cq != nil {
+		active, inadmissible = cq.PendingInLocalQueue(lq.Key)
+	}
 	if m.statusChecker != nil && !m.statusChecker.ClusterQueueActive(lq.ClusterQueue) {
 		inadmissible += active
 		active = 0
@@ -708,8 +710,7 @@ func (m *Manager) reportLQPendingWorkloads(lq *LocalQueue) {
 }
 
 func (m *Manager) reportPendingWorkloads(cqName kueue.ClusterQueueReference, cq *ClusterQueue) {
-	active := cq.PendingActive()
-	inadmissible := cq.PendingInadmissible()
+	active, inadmissible := cq.Pending()
 	if m.statusChecker != nil && !m.statusChecker.ClusterQueueActive(cqName) {
 		inadmissible += active
 		active = 0
@@ -726,12 +727,11 @@ func (m *Manager) GetClusterQueueNames() []kueue.ClusterQueueReference {
 func (m *Manager) getClusterQueue(cqName kueue.ClusterQueueReference) *ClusterQueue {
 	m.RLock()
 	defer m.RUnlock()
-	return m.hm.ClusterQueue(cqName)
+	return m.getClusterQueueLockless(cqName)
 }
 
-func (m *Manager) getClusterQueueLockless(cqName kueue.ClusterQueueReference) (val *ClusterQueue, ok bool) {
-	val = m.hm.ClusterQueue(cqName)
-	return val, val != nil
+func (m *Manager) getClusterQueueLockless(cqName kueue.ClusterQueueReference) *ClusterQueue {
+	return m.hm.ClusterQueue(cqName)
 }
 
 func (m *Manager) PendingWorkloadsInfo(cqName kueue.ClusterQueueReference) []*workload.Info {
diff --git a/pkg/cache/scheduler/clusterqueue.go b/pkg/cache/scheduler/clusterqueue.go
index 53bb2ed0e..5b098d46f 100644
--- a/pkg/cache/scheduler/clusterqueue.go
+++ b/pkg/cache/scheduler/clusterqueue.go
@@ -276,10 +276,6 @@ func (c *clusterQueue) inactiveReason() (string, string) {
 		}
 
 		if features.Enabled(features.TopologyAwareScheduling) && len(c.tasFlavors) > 0 {
-			if len(c.multiKueueAdmissionChecks) > 0 {
-				reasons = append(reasons, kueue.ClusterQueueActiveReasonNotSupportedWithTopologyAwareScheduling)
-				messages = append(messages, "TAS is not supported with MultiKueue admission check")
-			}
 			for tasFlavor, topology := range c.tasFlavors {
 				if c.tasCache.Get(tasFlavor) == nil {
 					reasons = append(reasons, kueue.ClusterQueueActiveReasonTopologyNotFound)
@@ -301,10 +297,14 @@ func (c *clusterQueue) isTASViolated() bool {
 	if !features.Enabled(features.TopologyAwareScheduling) || len(c.tasFlavors) == 0 {
 		return false
 	}
+	// Skip TAS cache validation when MultiKueue is enabled; topology runs on worker clusters.
+	if c.hasMultiKueueAdmissionCheck() {
+		return false
+	}
 	if !c.isTASSynced() {
 		return true
 	}
-	return len(c.multiKueueAdmissionChecks) > 0
+	return false
 }
 
 // UpdateWithFlavors updates a ClusterQueue based on the passed ResourceFlavors set.
@@ -641,3 +641,7 @@ func (c *clusterQueue) flavorsWithProvReqAdmissionCheck() sets.Set[kueue.Resourc
 	}
 	return flvs
 }
+
+func (c *clusterQueue) hasMultiKueueAdmissionCheck() bool {
+	return len(c.multiKueueAdmissionChecks) > 0
+}
diff --git a/pkg/cache/scheduler/clusterqueue_snapshot.go b/pkg/cache/scheduler/clusterqueue_snapshot.go
index 6ba132098..1dfa4bdf3 100644
--- a/pkg/cache/scheduler/clusterqueue_snapshot.go
+++ b/pkg/cache/scheduler/clusterqueue_snapshot.go
@@ -59,6 +59,7 @@ type ClusterQueueSnapshot struct {
 	tasOnly    bool
 
 	flavorsForProvReqACs sets.Set[kueue.ResourceFlavorReference]
+	hasMultiKueueAC      bool
 }
 
 // RGByResource returns the ResourceGroup which contains capacity
@@ -216,6 +217,10 @@ func (c *ClusterQueueSnapshot) HasProvRequestAdmissionCheck(rf kueue.ResourceFla
 	return c.flavorsForProvReqACs.Has(rf)
 }
 
+func (c *ClusterQueueSnapshot) HasMultiKueueAdmissionCheck() bool {
+	return c.hasMultiKueueAC
+}
+
 // Returns all ancestors starting with parent and ending with root
 func (c *ClusterQueueSnapshot) PathParentToRoot() iter.Seq[*CohortSnapshot] {
 	return func(yield func(*CohortSnapshot) bool) {
diff --git a/pkg/cache/scheduler/snapshot.go b/pkg/cache/scheduler/snapshot.go
index da410c69f..b3c640502 100644
--- a/pkg/cache/scheduler/snapshot.go
+++ b/pkg/cache/scheduler/snapshot.go
@@ -222,6 +222,7 @@ func (c *Cache) snapshotClusterQueue(ctx context.Context, cq *clusterQueue, afsE
 		TASFlavors:                    make(map[kueue.ResourceFlavorReference]*TASFlavorSnapshot),
 		tasOnly:                       cq.isTASOnly(),
 		flavorsForProvReqACs:          cq.flavorsWithProvReqAdmissionCheck(),
+		hasMultiKueueAC:               cq.hasMultiKueueAdmissionCheck(),
 	}
 	for i, rg := range cq.ResourceGroups {
 		cc.ResourceGroups[i] = rg.Clone()
diff --git a/pkg/cache/scheduler/tas_balanced_placement.go b/pkg/cache/scheduler/tas_balanced_placement.go
new file mode 100644
index 000000000..758aaed60
--- /dev/null
+++ b/pkg/cache/scheduler/tas_balanced_placement.go
@@ -0,0 +1,320 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package scheduler
+
+import (
+	"maps"
+	"math"
+	"slices"
+
+	utilslices "sigs.k8s.io/kueue/pkg/util/slices"
+)
+
+// evaluateGreedyAssignment simulates placement of a (leaderCount, sliceCount) request on the given domains.
+// It returns whether the request fits, how many domains greedy algorithm uses and what would be the last
+// used domain (with and without leader)
+func evaluateGreedyAssignment(s *TASFlavorSnapshot, domains []*domain, sliceCount int32, leaderCount int32) (bool, int32, *domain, *domain) {
+	var selectedDomainsCount int32
+	var sortedWithoutLeader, sortedWithLeader []*domain
+	var lastDomain, lastDomainWithLeader *domain
+	remainingSliceCount := sliceCount
+	remainingLeaderCount := leaderCount
+	idx := 0
+	if leaderCount > 0 {
+		sortedWithLeader = s.sortedDomainsWithLeader(domains, false)
+		for ; remainingLeaderCount > 0 && idx < len(sortedWithLeader) && sortedWithLeader[idx].leaderState > 0; idx++ {
+			selectedDomainsCount++
+			lastDomainWithLeader = sortedWithLeader[idx]
+			remainingLeaderCount -= sortedWithLeader[idx].leaderState
+			remainingSliceCount -= sortedWithLeader[idx].sliceStateWithLeader
+		}
+		sortedWithoutLeader = s.sortedDomains(sortedWithLeader[idx:], false)
+	} else {
+		sortedWithoutLeader = s.sortedDomains(domains, false)
+	}
+
+	if remainingLeaderCount > 0 {
+		return false, 0, nil, nil
+	}
+
+	for idx = 0; remainingSliceCount > 0 && idx < len(sortedWithoutLeader) && sortedWithoutLeader[idx].sliceState > 0; idx++ {
+		selectedDomainsCount++
+		lastDomain = sortedWithoutLeader[idx]
+		remainingSliceCount -= sortedWithoutLeader[idx].sliceState
+	}
+	if remainingSliceCount > 0 {
+		return false, 0, nil, nil
+	}
+	return true, selectedDomainsCount, lastDomainWithLeader, lastDomain
+}
+
+// The balance threshold value is maximum possible minimum number of slices placed on a domain in a balanced placement solution.
+func balanceThresholdValue(sliceCount int32, selectedDomainsCount int32, lastDomainWithLeader *domain, lastDomain *domain) int32 {
+	threshold := sliceCount / selectedDomainsCount
+	if lastDomainWithLeader != nil {
+		threshold = min(threshold, lastDomainWithLeader.sliceStateWithLeader)
+	}
+	if lastDomain != nil {
+		// TODO: https://github.com/kubernetes-sigs/kueue/issues/7494
+		// we don't have min(threshold, lastDomain.sliceState) here because
+		// later we prune all nodes with sliceStateWithLeader < threshold
+		// while pruning we don't know which node will host the leader
+		// so we have to leave space on each node
+		threshold = min(threshold, lastDomain.sliceStateWithLeader)
+	}
+	return threshold
+}
+
+// selectOptimalDomainSetToFit finds a subset of the provided domains that can accommodate
+// the request (sliceCount, leaderCount). It uses dynamic programming to find a combination
+// of domains that can fit the requested number of leaders and slices, using the minimum number
+// of domains possible (as determined by a greedy assignment) and having the minimum total capacity.
+func selectOptimalDomainSetToFit(s *TASFlavorSnapshot, domains []*domain, sliceCount int32, leaderCount int32, sliceSize int32, priorizeByEntropy bool) []*domain {
+	fit, optimalNumberOfDomains, _, _ := evaluateGreedyAssignment(s, domains, sliceCount, leaderCount)
+	if !fit {
+		return nil
+	}
+
+	if priorizeByEntropy {
+		sortDomainsByCapacityAndEntropy(domains)
+	}
+
+	// domain_placements[i][j][k] stores a list of domains that uses 'i' domains with
+	// ('j' leaders and 'k' workers) left to fit
+	domainPlacements := make([]map[int32]map[int32][]*domain, optimalNumberOfDomains+1)
+	for i := range domainPlacements {
+		domainPlacements[i] = make(map[int32]map[int32][]*domain)
+	}
+	domainPlacements[0][leaderCount] = map[int32][]*domain{sliceCount * sliceSize: {}}
+
+	for _, d := range domains {
+		for i := optimalNumberOfDomains; i > 0; i-- {
+			for _, beforeLeader := range slices.Sorted(maps.Keys(domainPlacements[i-1])) {
+				for _, beforeState := range slices.Sorted(maps.Keys(domainPlacements[i-1][beforeLeader])) {
+					beforePlacement := domainPlacements[i-1][beforeLeader][beforeState]
+					if beforeLeader <= 0 && beforeState <= 0 {
+						continue
+					}
+					newPlacement := make([]*domain, len(beforePlacement), len(beforePlacement)+1)
+					copy(newPlacement, beforePlacement)
+					newPlacement = append(newPlacement, d)
+					// Case 1: Pick this domain with leader
+					if beforeLeader > 0 && d.leaderState > 0 {
+						afterLeader := beforeLeader - d.leaderState
+						afterState := beforeState - d.stateWithLeader
+						if domainPlacements[i][afterLeader] == nil {
+							domainPlacements[i][afterLeader] = make(map[int32][]*domain)
+						}
+						if _, alreadyThere := domainPlacements[i][afterLeader][afterState]; !alreadyThere {
+							domainPlacements[i][afterLeader][afterState] = newPlacement
+						}
+					}
+					// Case 2: Pick this domain without leader
+					if d.sliceState > 0 {
+						afterState := beforeState - d.state
+						if domainPlacements[i][beforeLeader] == nil {
+							domainPlacements[i][beforeLeader] = make(map[int32][]*domain)
+						}
+						if _, alreadyThere := domainPlacements[i][beforeLeader][afterState]; !alreadyThere {
+							domainPlacements[i][beforeLeader][afterState] = newPlacement
+						}
+					}
+				}
+			}
+		}
+	}
+
+	bestLeaderPlacement := domainPlacements[optimalNumberOfDomains][0]
+	bestSlice := int32(-1 << 31) // minus infinity
+	var bestSlicePlacement []*domain
+
+	for _, slicesLeft := range slices.Sorted(maps.Keys(bestLeaderPlacement)) {
+		if slicesLeft > bestSlice && slicesLeft <= 0 {
+			bestSlice = slicesLeft
+			bestSlicePlacement = bestLeaderPlacement[slicesLeft]
+		}
+	}
+	return bestSlicePlacement
+}
+
+func placeSlicesOnDomainsBalanced(s *TASFlavorSnapshot, domains []*domain, sliceCount int32, leaderCount int32, sliceSize int32, threshold int32) ([]*domain, string) {
+	resultDomains := selectOptimalDomainSetToFit(s, domains, sliceCount, leaderCount, sliceSize, false)
+	if resultDomains == nil {
+		return nil, "TAS Balanced Placement: Cannot find optimal domain set to fit the request"
+	}
+	if sliceCount < int32(len(resultDomains))*threshold {
+		return nil, "TAS Balanced Placement: Not enough slices to meet the threshold"
+	}
+	resultDomains = s.sortedDomainsWithLeader(resultDomains, false)
+	extraSlicesLeft := sliceCount - int32(len(resultDomains))*threshold
+	leadersLeft := leaderCount
+	var extraSlicesToTake int32
+	for _, domain := range resultDomains {
+		switch {
+		case leadersLeft > 0:
+			extraSlicesToTake = min(domain.sliceStateWithLeader-threshold, extraSlicesLeft)
+			domain.leaderState = 1
+			leadersLeft--
+		case extraSlicesLeft > 0:
+			extraSlicesToTake = min(domain.sliceState-threshold, extraSlicesLeft)
+			domain.leaderState = 0
+		default:
+			domain.leaderState = 0
+			extraSlicesToTake = 0
+		}
+		domain.state = (threshold + extraSlicesToTake) * sliceSize
+		domain.sliceState = (threshold + extraSlicesToTake)
+		domain.sliceStateWithLeader = domain.sliceState
+		domain.stateWithLeader = domain.state - domain.leaderState
+		extraSlicesLeft -= extraSlicesToTake
+	}
+	if extraSlicesLeft > 0 || leadersLeft > 0 {
+		return nil, "TAS Balanced Placement: Not all slices or leaders could be placed"
+	}
+	return resultDomains, ""
+}
+
+func calculateEntropy(blockSizes []int32) float64 {
+	if len(blockSizes) == 0 {
+		return 0.0
+	}
+
+	var total int32
+	for _, size := range blockSizes {
+		total += size
+	}
+
+	if total == 0 {
+		return 0.0
+	}
+
+	var entropy float64
+	totalF := float64(total)
+	for _, size := range blockSizes {
+		if size > 0 {
+			pI := float64(size) / totalF
+			entropy += -pI * math.Log2(pI)
+		}
+	}
+	return entropy
+}
+
+func sortDomainsByCapacityAndEntropy(domains []*domain) {
+	slices.SortFunc(domains, func(a, b *domain) int {
+		if r := b.leaderState - a.leaderState; r != 0 {
+			return int(r)
+		}
+		if r := b.sliceStateWithLeader - a.sliceStateWithLeader; r != 0 {
+			return int(r)
+		}
+		aChildrenCapacities := utilslices.Map(a.children, func(d **domain) int32 { return (*d).state })
+		bChildrenCapacities := utilslices.Map(b.children, func(d **domain) int32 { return (*d).state })
+		aEntropy := calculateEntropy(aChildrenCapacities)
+		bEntropy := calculateEntropy(bChildrenCapacities)
+		if bEntropy > aEntropy {
+			return 1
+		}
+		if bEntropy < aEntropy {
+			return -1
+		}
+		return 0
+	})
+}
+
+// findBestDomainsForBalancedPlacement evaluates domains for balanced placement.
+// It returns the best set of domains, the balance threshold, and whether a balanced placement is possible.
+func findBestDomainsForBalancedPlacement(s *TASFlavorSnapshot, levelIdx, sliceLevelIdx int, count, leaderCount, sliceSize int32) ([]*domain, int32, bool) {
+	// check if balanced placement is possible: look one level above the preferred level
+	// see if any (single) domain on that level fits the request and compute for each of
+	// them the balance threshold value
+	sliceCount := count / sliceSize
+	var requestedLevelDomainsToConsider [][]*domain
+	if levelIdx == 0 {
+		requestedLevelDomainsToConsider = [][]*domain{slices.Collect(maps.Values(s.domainsPerLevel[0]))}
+	} else {
+		for _, higherLevelDomain := range slices.Collect(maps.Values(s.domainsPerLevel[levelIdx-1])) {
+			requestedLevelDomainsToConsider = append(requestedLevelDomainsToConsider, higherLevelDomain.children)
+		}
+	}
+
+	var bestThreshold int32
+	var bestDomainCountOnRequestedLevel int32
+	var currFitDomain []*domain
+	useBalancedPlacement := false
+
+	for _, requestedLevelSiblingDomains := range requestedLevelDomainsToConsider {
+		lowerLevelDomains := getLowerLevelDomains(s, requestedLevelSiblingDomains, levelIdx, sliceLevelIdx)
+		fits, selectedDomainsCount, lastDomainWithLeader, lastDomain := evaluateGreedyAssignment(s, lowerLevelDomains, sliceCount, leaderCount)
+		if !fits {
+			continue
+		}
+		threshold := balanceThresholdValue(sliceCount, selectedDomainsCount, lastDomainWithLeader, lastDomain)
+		if threshold >= bestThreshold {
+			s.pruneDomainsBelowThreshold(requestedLevelSiblingDomains, threshold, sliceSize, sliceLevelIdx, levelIdx)
+			_, requestedLevelDomainCount, _, _ := evaluateGreedyAssignment(s, requestedLevelSiblingDomains, sliceCount, leaderCount)
+			if threshold > bestThreshold || (threshold == bestThreshold && requestedLevelDomainCount < bestDomainCountOnRequestedLevel) {
+				bestThreshold = threshold
+				bestDomainCountOnRequestedLevel = requestedLevelDomainCount
+				currFitDomain = requestedLevelSiblingDomains
+				useBalancedPlacement = true
+			}
+		}
+	}
+	return currFitDomain, bestThreshold, useBalancedPlacement
+}
+
+// applyBalancedPlacementAlgorithm applies the balanced placement algorithm to determine domain assignments.
+func applyBalancedPlacementAlgorithm(s *TASFlavorSnapshot, levelIdx, sliceLevelIdx int, count, leaderCount, sliceSize, bestThreshold int32, unconstrained bool, currFitDomain []*domain) ([]*domain, string) {
+	sliceCount := count / sliceSize
+	var fitLevelIdx int
+	if levelIdx < sliceLevelIdx {
+		resultDomains := selectOptimalDomainSetToFit(s, currFitDomain, sliceCount, leaderCount, sliceSize, true)
+		if resultDomains == nil {
+			return nil, "TAS Balanced Placement: Cannot find optimal domain set to fit the request"
+		}
+		currFitDomain = s.lowerLevelDomains(resultDomains)
+		fitLevelIdx = levelIdx + 1
+	} else {
+		fitLevelIdx = levelIdx
+	}
+	var reason string
+	currFitDomain, reason = placeSlicesOnDomainsBalanced(s, currFitDomain, sliceCount, leaderCount, sliceSize, bestThreshold)
+	if len(reason) > 0 {
+		return nil, reason
+	}
+	for currentLevelIdx := fitLevelIdx; currentLevelIdx+1 < len(s.domainsPerLevel); currentLevelIdx++ {
+		sliceSizeOnLevel := sliceSize
+		if currentLevelIdx >= sliceLevelIdx {
+			sliceSizeOnLevel = 1
+		}
+		newCurrFitDomain := make([]*domain, 0)
+		for _, domain := range currFitDomain {
+			sortedLowerDomains := s.sortedDomains(domain.children, unconstrained)
+			addCurrFitDomain := s.updateCountsToMinimumGeneric(sortedLowerDomains, domain.state, domain.leaderState, sliceSizeOnLevel, unconstrained, currentLevelIdx < sliceLevelIdx)
+			newCurrFitDomain = append(newCurrFitDomain, addCurrFitDomain...)
+		}
+		currFitDomain = newCurrFitDomain
+	}
+	return currFitDomain, ""
+}
+
+func getLowerLevelDomains(s *TASFlavorSnapshot, domains []*domain, levelIdx, sliceLevelIdx int) []*domain {
+	if levelIdx < sliceLevelIdx {
+		return s.lowerLevelDomains(domains)
+	}
+	return domains
+}
diff --git a/pkg/cache/scheduler/tas_flavor_snapshot.go b/pkg/cache/scheduler/tas_flavor_snapshot.go
index c0e86ba3b..6f5fce89d 100644
--- a/pkg/cache/scheduler/tas_flavor_snapshot.go
+++ b/pkg/cache/scheduler/tas_flavor_snapshot.go
@@ -741,33 +741,50 @@ func (s *TASFlavorSnapshot) findTopologyAssignment(
 
 	// phase 2a: determine the level at which the assignment is done along with
 	// the domains which can accommodate all pods/slices
-	fitLevelIdx, currFitDomain, reason := s.findLevelWithFitDomains(levelIdx, required, count, leaderCount, sliceSize, unconstrained)
-	if len(reason) > 0 {
-		return nil, reason
+	var currFitDomain []*domain
+	var fitLevelIdx int
+	var useBalancedPlacement bool
+	if features.Enabled(features.TASBalancedPlacement) && !required && !unconstrained {
+		var bestThreshold int32
+		currFitDomain, bestThreshold, useBalancedPlacement = findBestDomainsForBalancedPlacement(s, levelIdx, sliceLevelIdx, count, leaderCount, sliceSize)
+
+		if useBalancedPlacement {
+			currFitDomain, reason = applyBalancedPlacementAlgorithm(s, levelIdx, sliceLevelIdx, count, leaderCount, sliceSize, bestThreshold, unconstrained, currFitDomain)
+			if len(reason) > 0 {
+				return nil, reason
+			}
+		}
 	}
 
-	// phase 2b: traverse the tree down level-by-level optimizing the number of
-	// topology domains at each level
-	// if unconstrained is set, we'll only do it once
-	currFitDomain = s.updateCountsToMinimumGeneric(currFitDomain, count, leaderCount, sliceSize, unconstrained, true)
-	for levelIdx := fitLevelIdx; levelIdx+1 < len(s.domainsPerLevel); levelIdx++ {
-		if levelIdx < sliceLevelIdx {
-			// If we are "above" the requested slice topology level, we're greedily assigning pods/slices to
-			// all domains without checking what we've assigned to parent domains.
-			sortedLowerDomains := s.sortedDomains(s.lowerLevelDomains(currFitDomain), unconstrained)
-			currFitDomain = s.updateCountsToMinimumGeneric(sortedLowerDomains, count, leaderCount, sliceSize, unconstrained, true)
-		} else {
-			// If we are "at" or "below" the requested slice topology level, we have to carefully assign pods
-			// to domains based on what we've assigned to parent domains, that's why we're iterating through
-			// each parent domain and assigning `domain.state` amount of pods its child domains.
-			newCurrFitDomain := make([]*domain, 0)
-			for _, domain := range currFitDomain {
-				sortedLowerDomains := s.sortedDomains(domain.children, unconstrained)
-
-				addCurrFitDomain := s.updateCountsToMinimumGeneric(sortedLowerDomains, domain.state, domain.leaderState, 1, unconstrained, false)
-				newCurrFitDomain = append(newCurrFitDomain, addCurrFitDomain...)
+	if !useBalancedPlacement {
+		fitLevelIdx, currFitDomain, reason = s.findLevelWithFitDomains(levelIdx, required, count, leaderCount, sliceSize, unconstrained)
+		if len(reason) > 0 {
+			return nil, reason
+		}
+		// phase 2b: traverse the tree down level-by-level optimizing the number of
+		// topology domains at each level
+		// if unconstrained is set, we'll only do it once
+		currFitDomain = s.updateCountsToMinimumGeneric(currFitDomain, count, leaderCount, sliceSize, unconstrained, true)
+
+		for levelIdx := fitLevelIdx; levelIdx+1 < len(s.domainsPerLevel); levelIdx++ {
+			if levelIdx < sliceLevelIdx {
+				// If we are "above" the requested slice topology level, we're greedily assigning pods/slices to
+				// all domains without checking what we've assigned to parent domains.
+				sortedLowerDomains := s.sortedDomains(s.lowerLevelDomains(currFitDomain), unconstrained)
+				currFitDomain = s.updateCountsToMinimumGeneric(sortedLowerDomains, count, leaderCount, sliceSize, unconstrained, true)
+			} else {
+				// If we are "at" or "below" the requested slice topology level, we have to carefully assign pods
+				// to domains based on what we've assigned to parent domains, that's why we're iterating through
+				// each parent domain and assigning `domain.state` amount of pods its child domains.
+				newCurrFitDomain := make([]*domain, 0)
+				for _, domain := range currFitDomain {
+					sortedLowerDomains := s.sortedDomains(domain.children, unconstrained)
+
+					addCurrFitDomain := s.updateCountsToMinimumGeneric(sortedLowerDomains, domain.state, domain.leaderState, 1, unconstrained, false)
+					newCurrFitDomain = append(newCurrFitDomain, addCurrFitDomain...)
+				}
+				currFitDomain = newCurrFitDomain
 			}
-			currFitDomain = newCurrFitDomain
 		}
 	}
 
@@ -1415,6 +1432,33 @@ func (s *TASFlavorSnapshot) notFitMessage(slicesFitCount, totalRequestsSlicesCou
 	return fmt.Sprintf("topology %q allows to fit only %d out of %d slice(s)", s.topologyName, slicesFitCount, totalRequestsSlicesCount)
 }
 
+func clearState(d *domain) {
+	d.state = int32(0)
+	d.sliceState = int32(0)
+	d.stateWithLeader = int32(0)
+	d.sliceStateWithLeader = int32(0)
+	d.leaderState = int32(0)
+	for _, child := range d.children {
+		clearState(child)
+	}
+}
+
+func (s *TASFlavorSnapshot) pruneDomainsBelowThreshold(domains []*domain, threshold int32, sliceSize int32, sliceLevelIdx int, level int) {
+	for _, d := range domains {
+		for _, c := range d.children {
+			if c.sliceStateWithLeader < threshold {
+				clearState(c)
+			}
+		}
+	}
+	for _, d := range domains {
+		d.state, d.sliceState, d.stateWithLeader, d.sliceStateWithLeader, d.leaderState = s.fillInCountsHelper(d, sliceSize, sliceLevelIdx, level)
+		if d.sliceStateWithLeader < threshold {
+			clearState(d)
+		}
+	}
+}
+
 func slicesRequested(tr *kueue.PodSetTopologyRequest) bool {
 	return tr != nil && tr.PodSetSliceRequiredTopology != nil && tr.PodSetSliceSize != nil
 }
diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go
index 856bbf038..b8b750745 100644
--- a/pkg/constants/constants.go
+++ b/pkg/constants/constants.go
@@ -32,12 +32,9 @@ const (
 	UpdatesBatchPeriod = time.Second
 
 	// DefaultPriority is used to set priority of workloads
-	// that do not specify any priority class and there is no priority class
+	// that do not specify any priority class, and there is no priority class
 	// marked as default.
-	DefaultPriority = 0
-
-	WorkloadPriorityClassSource = "kueue.x-k8s.io/workloadpriorityclass"
-	PodPriorityClassSource      = "scheduling.k8s.io/priorityclass"
+	DefaultPriority int32 = 0
 
 	DefaultPendingWorkloadsLimit = 1000
 
diff --git a/pkg/controller/admissionchecks/multikueue/workload.go b/pkg/controller/admissionchecks/multikueue/workload.go
index 7c3f692d9..d2db66bd6 100644
--- a/pkg/controller/admissionchecks/multikueue/workload.go
+++ b/pkg/controller/admissionchecks/multikueue/workload.go
@@ -34,6 +34,7 @@ import (
 	"k8s.io/client-go/util/workqueue"
 	"k8s.io/klog/v2"
 	"k8s.io/utils/clock"
+	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -45,10 +46,8 @@ import (
 	config "sigs.k8s.io/kueue/apis/config/v1beta2"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	"sigs.k8s.io/kueue/pkg/controller/jobframework"
-	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/util/admissioncheck"
 	"sigs.k8s.io/kueue/pkg/util/api"
-	clientutil "sigs.k8s.io/kueue/pkg/util/client"
 	utilmaps "sigs.k8s.io/kueue/pkg/util/maps"
 	"sigs.k8s.io/kueue/pkg/workload"
 	"sigs.k8s.io/kueue/pkg/workloadslicing"
@@ -358,24 +357,8 @@ func (w *wlReconciler) reconcileGroup(ctx context.Context, group *wlGroup) (reco
 			log.V(3).Info("Group with no adapter, skip owner status copy", "workerCluster", remote)
 		}
 
-		// copy the status to the local one
-		finishCond := metav1.Condition{
-			Type:               kueue.WorkloadFinished,
-			Status:             metav1.ConditionTrue,
-			Reason:             remoteFinishedCond.Reason,
-			Message:            remoteFinishedCond.Message,
-			LastTransitionTime: metav1.NewTime(w.clock.Now()),
-		}
-		if features.Enabled(features.WorkloadRequestUseMergePatch) {
-			return reconcile.Result{}, clientutil.PatchStatus(ctx, w.client, group.local, func() (client.Object, bool, error) {
-				apimeta.SetStatusCondition(&group.local.Status.Conditions, finishCond)
-				return group.local, true, nil
-			})
-		}
-
-		wlPatch := workload.BaseSSAWorkload(group.local, false)
-		apimeta.SetStatusCondition(&wlPatch.Status.Conditions, finishCond)
-		return reconcile.Result{}, w.client.Status().Patch(ctx, wlPatch, client.Apply, client.FieldOwner(kueue.MultiKueueControllerName+"-finish"), client.ForceOwnership)
+		// finish workload and copy the status to the local one
+		return reconcile.Result{}, workload.Finish(ctx, w.client, group.local, remoteFinishedCond.Reason, remoteFinishedCond.Message, kueue.MultiKueueControllerName, w.clock)
 	}
 
 	// 2. delete all workloads that are out of sync (other than scaled-down elastic workloads)
@@ -420,28 +403,8 @@ func (w *wlReconciler) reconcileGroup(ctx context.Context, group *wlGroup) (reco
 			return reconcile.Result{}, err
 		}
 
-		if acs.State != kueue.CheckStateRetry && acs.State != kueue.CheckStateRejected {
-			if err := workload.PatchAdmissionStatus(ctx, w.client, group.local, w.clock, func() (*kueue.Workload, bool, error) {
-				if group.jobAdapter.KeepAdmissionCheckPending() {
-					acs.State = kueue.CheckStatePending
-				} else {
-					acs.State = kueue.CheckStateReady
-				}
-				// update the message
-				acs.Message = fmt.Sprintf("The workload got reservation on %q", reservingRemote)
-				// update the transition time since is used to detect the lost worker state.
-				acs.LastTransitionTime = metav1.NewTime(w.clock.Now())
-
-				workload.SetAdmissionCheckState(&group.local.Status.AdmissionChecks, *acs, w.clock)
-				// Set the cluster name to the reserving remote and clear the nominated clusters.
-				group.local.Status.ClusterName = &reservingRemote
-				group.local.Status.NominatedClusterNames = nil
-				return group.local, true, nil
-			}); err != nil {
-				log.V(2).Error(err, "Failed to patch workload", "workload", klog.KObj(group.local))
-				return reconcile.Result{}, err
-			}
-			w.recorder.Eventf(group.local, corev1.EventTypeNormal, "MultiKueue", acs.Message)
+		if err := w.syncReservingRemoteState(ctx, group, reservingRemote, acs); err != nil {
+			return reconcile.Result{}, err
 		}
 		return reconcile.Result{RequeueAfter: w.workerLostTimeout}, nil
 	} else if acs.State == kueue.CheckStateReady {
@@ -637,6 +600,109 @@ func (w *wlReconciler) setupWithManager(mgr ctrl.Manager) error {
 		Complete(w)
 }
 
+func findPodSetAssignment(assignments []kueue.PodSetAssignment, name kueue.PodSetReference) *kueue.PodSetAssignment {
+	for i := range assignments {
+		if assignments[i].Name == name {
+			return &assignments[i]
+		}
+	}
+	return nil
+}
+
+func needsDelayedTopologyUpdate(local, remote *kueue.Workload) bool {
+	if remote == nil || remote.Status.Admission == nil || local == nil || local.Status.Admission == nil {
+		return false
+	}
+
+	for _, remotePSA := range remote.Status.Admission.PodSetAssignments {
+		if remotePSA.TopologyAssignment == nil {
+			continue
+		}
+
+		localPSA := findPodSetAssignment(local.Status.Admission.PodSetAssignments, remotePSA.Name)
+		if localPSA == nil {
+			continue
+		}
+
+		if localPSA.TopologyAssignment == nil {
+			return true
+		}
+
+		if localPSA.DelayedTopologyRequest != nil &&
+			*localPSA.DelayedTopologyRequest == kueue.DelayedTopologyRequestStatePending {
+			return true
+		}
+	}
+	return false
+}
+
+func (w *wlReconciler) syncReservingRemoteState(ctx context.Context, group *wlGroup, reservingRemote string, acs *kueue.AdmissionCheckState) error {
+	log := ctrl.LoggerFrom(ctx)
+
+	needsTopologyUpdate := needsDelayedTopologyUpdate(group.local, group.remotes[reservingRemote])
+	needsACUpdate := acs.State != kueue.CheckStateRetry && acs.State != kueue.CheckStateRejected
+
+	if !needsTopologyUpdate && !needsACUpdate {
+		return nil
+	}
+
+	if err := workload.PatchAdmissionStatus(ctx, w.client, group.local, w.clock, func() (*kueue.Workload, bool, error) {
+		if needsTopologyUpdate {
+			updateDelayedTopologyRequest(group.local, group.remotes[reservingRemote])
+		}
+
+		if needsACUpdate {
+			if group.jobAdapter.KeepAdmissionCheckPending() {
+				acs.State = kueue.CheckStatePending
+			} else {
+				acs.State = kueue.CheckStateReady
+			}
+			// update the message
+			acs.Message = fmt.Sprintf("The workload got reservation on %q", reservingRemote)
+			// update the transition time since is used to detect the lost worker state.
+			acs.LastTransitionTime = metav1.NewTime(w.clock.Now())
+
+			workload.SetAdmissionCheckState(&group.local.Status.AdmissionChecks, *acs, w.clock)
+			// Set the cluster name to the reserving remote and clear the nominated clusters.
+			group.local.Status.ClusterName = &reservingRemote
+			group.local.Status.NominatedClusterNames = nil
+		}
+
+		return group.local, true, nil
+	}); err != nil {
+		log.V(2).Error(err, "Failed to patch workload", "workload", klog.KObj(group.local))
+		return err
+	}
+
+	if needsACUpdate {
+		w.recorder.Eventf(group.local, corev1.EventTypeNormal, "MultiKueue", acs.Message)
+	}
+
+	return nil
+}
+
+func updateDelayedTopologyRequest(local, remote *kueue.Workload) {
+	if remote == nil || remote.Status.Admission == nil || local == nil || local.Status.Admission == nil {
+		return
+	}
+
+	for _, remotePSA := range remote.Status.Admission.PodSetAssignments {
+		if remotePSA.TopologyAssignment == nil {
+			continue
+		}
+
+		localPSA := findPodSetAssignment(local.Status.Admission.PodSetAssignments, remotePSA.Name)
+		if localPSA == nil {
+			continue
+		}
+
+		if localPSA.DelayedTopologyRequest != nil &&
+			*localPSA.DelayedTopologyRequest == kueue.DelayedTopologyRequestStatePending {
+			localPSA.DelayedTopologyRequest = ptr.To(kueue.DelayedTopologyRequestStateReady)
+		}
+	}
+}
+
 func cloneForCreate(orig *kueue.Workload, origin string) *kueue.Workload {
 	remoteWl := &kueue.Workload{}
 	remoteWl.ObjectMeta = api.CloneObjectMetaForCreation(&orig.ObjectMeta)
diff --git a/pkg/controller/core/workload_controller.go b/pkg/controller/core/workload_controller.go
index cc74f3ee1..1ef0d461f 100644
--- a/pkg/controller/core/workload_controller.go
+++ b/pkg/controller/core/workload_controller.go
@@ -52,7 +52,6 @@ import (
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	qcache "sigs.k8s.io/kueue/pkg/cache/queue"
 	schdcache "sigs.k8s.io/kueue/pkg/cache/scheduler"
-	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/core/indexer"
 	"sigs.k8s.io/kueue/pkg/dra"
 	"sigs.k8s.io/kueue/pkg/features"
@@ -388,17 +387,18 @@ func (r *WorkloadReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 			quotaReservedCondition := apimeta.FindStatusCondition(wl.Status.Conditions, kueue.WorkloadQuotaReserved)
 			quotaReservedWaitTime := r.clock.Since(quotaReservedCondition.LastTransitionTime.Time)
 			r.recorder.Eventf(&wl, corev1.EventTypeNormal, "Admitted", "Admitted by ClusterQueue %v, wait time since reservation was %.0fs", wl.Status.Admission.ClusterQueue, quotaReservedWaitTime.Seconds())
-			metrics.AdmittedWorkload(cqName, wl.Spec.PriorityClassName, queuedWaitTime)
-			metrics.ReportAdmissionChecksWaitTime(cqName, wl.Spec.PriorityClassName, quotaReservedWaitTime)
+			priorityClassName := workload.PriorityClassName(&wl)
+			metrics.AdmittedWorkload(cqName, priorityClassName, queuedWaitTime)
+			metrics.ReportAdmissionChecksWaitTime(cqName, priorityClassName, quotaReservedWaitTime)
 			if features.Enabled(features.LocalQueueMetrics) {
 				metrics.LocalQueueAdmittedWorkload(
 					metrics.LQRefFromWorkload(&wl),
-					wl.Spec.PriorityClassName,
+					priorityClassName,
 					queuedWaitTime,
 				)
 				metrics.ReportLocalQueueAdmissionChecksWaitTime(
 					metrics.LQRefFromWorkload(&wl),
-					wl.Spec.PriorityClassName,
+					priorityClassName,
 					quotaReservedWaitTime,
 				)
 			}
@@ -924,10 +924,9 @@ func (r *WorkloadReconciler) Update(e event.TypedUpdateEvent[*kueue.Workload]) b
 }
 
 func workloadPriorityClassChanged(old, new *kueue.Workload) bool {
-	return old.Spec.PriorityClassSource == constants.WorkloadPriorityClassSource &&
-		new.Spec.PriorityClassSource == constants.WorkloadPriorityClassSource &&
-		old.Spec.PriorityClassName != "" && new.Spec.PriorityClassName != "" &&
-		old.Spec.PriorityClassName != new.Spec.PriorityClassName
+	return workload.IsWorkloadPriorityClass(old) && workload.IsWorkloadPriorityClass(new) &&
+		workload.PriorityClassName(old) != "" && workload.PriorityClassName(new) != "" &&
+		workload.PriorityClassName(old) != workload.PriorityClassName(new)
 }
 
 func (r *WorkloadReconciler) Generic(e event.TypedGenericEvent[*kueue.Workload]) bool {
diff --git a/pkg/controller/jobframework/reconciler.go b/pkg/controller/jobframework/reconciler.go
index ef7a5a6c8..c56c22afb 100644
--- a/pkg/controller/jobframework/reconciler.go
+++ b/pkg/controller/jobframework/reconciler.go
@@ -452,12 +452,12 @@ func (r *JobReconciler) ReconcileGenericJob(ctx context.Context, req ctrl.Reques
 	// 2. handle job is finished.
 	if message, success, finished := job.Finished(ctx); finished {
 		log.V(3).Info("The workload is already finished")
-		if wl != nil && !apimeta.IsStatusConditionTrue(wl.Status.Conditions, kueue.WorkloadFinished) {
+		if wl != nil && !workload.IsFinished(wl) {
 			reason := kueue.WorkloadFinishedReasonSucceeded
 			if !success {
 				reason = kueue.WorkloadFinishedReasonFailed
 			}
-			err := workload.UpdateStatus(ctx, r.client, wl, kueue.WorkloadFinished, metav1.ConditionTrue, reason, message, constants.JobControllerName, r.clock)
+			err := workload.Finish(ctx, r.client, wl, reason, message, constants.JobControllerName, r.clock)
 			if err != nil && !apierrors.IsNotFound(err) {
 				return ctrl.Result{}, err
 			}
@@ -522,18 +522,20 @@ func (r *JobReconciler) ReconcileGenericJob(ctx context.Context, req ctrl.Reques
 			err := workload.UpdateStatus(ctx, r.client, wl, condition.Type, condition.Status, condition.Reason, condition.Message, constants.JobControllerName, r.clock)
 			if err != nil {
 				log.Error(err, "Updating workload status")
+				return ctrl.Result{}, client.IgnoreNotFound(err)
 			}
 			// update the metrics only when PodsReady condition status is true
 			if condition.Status == metav1.ConditionTrue {
 				cqName := wl.Status.Admission.ClusterQueue
+				priorityClassName := workload.PriorityClassName(wl)
 				queuedUntilReadyWaitTime := workload.QueuedWaitTime(wl, r.clock)
-				metrics.ReadyWaitTime(cqName, wl.Spec.PriorityClassName, queuedUntilReadyWaitTime)
+				metrics.ReadyWaitTime(cqName, priorityClassName, queuedUntilReadyWaitTime)
 				admittedCond := apimeta.FindStatusCondition(wl.Status.Conditions, kueue.WorkloadAdmitted)
 				admittedUntilReadyWaitTime := condition.LastTransitionTime.Sub(admittedCond.LastTransitionTime.Time)
-				metrics.ReportAdmittedUntilReadyWaitTime(cqName, wl.Spec.PriorityClassName, admittedUntilReadyWaitTime)
+				metrics.ReportAdmittedUntilReadyWaitTime(cqName, priorityClassName, admittedUntilReadyWaitTime)
 				if features.Enabled(features.LocalQueueMetrics) {
-					metrics.LocalQueueReadyWaitTime(metrics.LQRefFromWorkload(wl), wl.Spec.PriorityClassName, queuedUntilReadyWaitTime)
-					metrics.ReportLocalQueueAdmittedUntilReadyWaitTime(metrics.LQRefFromWorkload(wl), wl.Spec.PriorityClassName, admittedUntilReadyWaitTime)
+					metrics.LocalQueueReadyWaitTime(metrics.LQRefFromWorkload(wl), priorityClassName, queuedUntilReadyWaitTime)
+					metrics.ReportLocalQueueAdmittedUntilReadyWaitTime(metrics.LQRefFromWorkload(wl), priorityClassName, admittedUntilReadyWaitTime)
 				}
 			}
 			return ctrl.Result{}, nil
@@ -582,7 +584,7 @@ func (r *JobReconciler) ReconcileGenericJob(ctx context.Context, req ctrl.Reques
 				log.Error(err, "Unsuspending job")
 				if podset.IsPermanent(err) {
 					// Mark the workload as finished with failure since the is no point to retry.
-					errUpdateStatus := workload.UpdateStatus(ctx, r.client, wl, kueue.WorkloadFinished, metav1.ConditionTrue, FailedToStartFinishedReason, err.Error(), constants.JobControllerName, r.clock)
+					errUpdateStatus := workload.Finish(ctx, r.client, wl, FailedToStartFinishedReason, err.Error(), constants.JobControllerName, r.clock)
 					if errUpdateStatus != nil {
 						log.Error(errUpdateStatus, "Updating workload status, on start failure", "err", err)
 					}
@@ -944,7 +946,7 @@ func (r *JobReconciler) ensureOneWorkload(ctx context.Context, job GenericJob, o
 
 // UpdateWorkloadPriority updates workload priority if object's kueue.x-k8s.io/priority-class label changed.
 func UpdateWorkloadPriority(ctx context.Context, c client.Client, r record.EventRecorder, obj client.Object, wl *kueue.Workload, customPriorityClassFunc func() string) error {
-	if wl.Spec.PriorityClassSource == constants.WorkloadPriorityClassSource && WorkloadPriorityClassName(obj) != wl.Spec.PriorityClassName {
+	if workload.IsWorkloadPriorityClass(wl) && WorkloadPriorityClassName(obj) != workload.PriorityClassName(wl) {
 		if err := PrepareWorkloadPriority(ctx, c, obj, wl, customPriorityClassFunc); err != nil {
 			return fmt.Errorf("prepare workload priority: %w", err)
 		}
@@ -1020,13 +1022,8 @@ func (r *JobReconciler) ensurePrebuiltWorkloadInSync(ctx context.Context, wl *ku
 			return false, err
 		}
 		// mark the workload as finished
-		err := workload.UpdateStatus(ctx, r.client, wl,
-			kueue.WorkloadFinished,
-			metav1.ConditionTrue,
-			kueue.WorkloadFinishedReasonOutOfSync,
-			"The prebuilt workload is out of sync with its user job",
-			constants.JobControllerName, r.clock)
-		return false, err
+		msg := "The prebuilt workload is out of sync with its user job"
+		return false, workload.Finish(ctx, r.client, wl, kueue.WorkloadFinishedReasonOutOfSync, msg, constants.JobControllerName, r.clock)
 	}
 	return true, nil
 }
@@ -1293,14 +1290,13 @@ func getCustomPriorityClassFuncFromJob(job GenericJob) func() string {
 }
 
 func PrepareWorkloadPriority(ctx context.Context, c client.Client, obj client.Object, wl *kueue.Workload, customPriorityClassFunc func() string) error {
-	priorityClassName, source, p, err := ExtractPriority(ctx, c, obj, wl.Spec.PodSets, customPriorityClassFunc)
+	priorityClassRef, priority, err := ExtractPriority(ctx, c, obj, wl.Spec.PodSets, customPriorityClassFunc)
 	if err != nil {
 		return err
 	}
 
-	wl.Spec.PriorityClassName = priorityClassName
-	wl.Spec.Priority = &p
-	wl.Spec.PriorityClassSource = source
+	wl.Spec.PriorityClassRef = priorityClassRef
+	wl.Spec.Priority = &priority
 
 	return nil
 }
@@ -1319,7 +1315,7 @@ func (r *JobReconciler) prepareWorkload(ctx context.Context, job GenericJob, wl
 	return nil
 }
 
-func ExtractPriority(ctx context.Context, c client.Client, obj client.Object, podSets []kueue.PodSet, customPriorityClassFunc func() string) (string, string, int32, error) {
+func ExtractPriority(ctx context.Context, c client.Client, obj client.Object, podSets []kueue.PodSet, customPriorityClassFunc func() string) (*kueue.PriorityClassRef, int32, error) {
 	if workloadPriorityClass := WorkloadPriorityClassName(obj); len(workloadPriorityClass) > 0 {
 		return utilpriority.GetPriorityFromWorkloadPriorityClass(ctx, c, workloadPriorityClass)
 	}
diff --git a/pkg/controller/jobs/job/job_multikueue_adapter.go b/pkg/controller/jobs/job/job_multikueue_adapter.go
index 378709ab2..16dde2d83 100644
--- a/pkg/controller/jobs/job/job_multikueue_adapter.go
+++ b/pkg/controller/jobs/job/job_multikueue_adapter.go
@@ -51,7 +51,7 @@ func (b *multiKueueAdapter) SyncJob(ctx context.Context, localClient client.Clie
 	localJob := batchv1.Job{}
 	err := localClient.Get(ctx, key, &localJob)
 	if err != nil {
-		fmt.Println("PROD: LOCAL JOB ERROR", err, key)
+		log.Error(err, "Failed to get local job", "key", key)
 		return err
 	}
 
diff --git a/pkg/controller/jobs/trainjob/trainjob_controller.go b/pkg/controller/jobs/trainjob/trainjob_controller.go
index c4c8d37b7..df44858a1 100644
--- a/pkg/controller/jobs/trainjob/trainjob_controller.go
+++ b/pkg/controller/jobs/trainjob/trainjob_controller.go
@@ -21,7 +21,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"sync"
 
 	kftrainer "github.com/kubeflow/trainer/v2/pkg/apis/trainer/v1alpha1"
 	kftrainerruntime "github.com/kubeflow/trainer/v2/pkg/runtime"
@@ -76,10 +75,9 @@ func init() {
 // +kubebuilder:rbac:groups=trainer.kubeflow.org,resources=clustertrainingruntimes,verbs=get;list;watch
 
 type trainJobReconciler struct {
-	jr               *jobframework.JobReconciler
-	runtimes         map[string]kftrainerruntime.Runtime
-	client           client.Client
-	runtimeInfoMutex sync.Mutex
+	jr       *jobframework.JobReconciler
+	runtimes map[string]kftrainerruntime.Runtime
+	client   client.Client
 }
 
 var reconciler trainJobReconciler
@@ -169,7 +167,7 @@ func getChildJobSet(ctx context.Context, t *TrainJob) (*jobsetapi.JobSet, error)
 	if err != nil {
 		return nil, fmt.Errorf("runtime '%s' not found", trainJob.Spec.RuntimeRef.Name)
 	}
-	info, err := reconciler.runtimeInfo(runtime, trainJob, trSpec)
+	info, err := runtime.RuntimeInfo(trainJob, trSpec.Template, trSpec.MLPolicy, trSpec.PodGroupPolicy)
 	if err != nil {
 		return nil, err
 	}
@@ -186,13 +184,6 @@ func getChildJobSet(ctx context.Context, t *TrainJob) (*jobsetapi.JobSet, error)
 	return jobsetApplyToJobset(jobsetApply)
 }
 
-// TODO: Remove mutex once RuntimeInfo gets thread safe - https://github.com/kubeflow/trainer/issues/2873
-func (r *trainJobReconciler) runtimeInfo(runtime kftrainerruntime.Runtime, trainJob *kftrainer.TrainJob, trSpec *kftrainer.TrainingRuntimeSpec) (*kftrainerruntime.Info, error) {
-	r.runtimeInfoMutex.Lock()
-	defer r.runtimeInfoMutex.Unlock()
-	return runtime.RuntimeInfo(trainJob, trSpec.Template, trSpec.MLPolicy, trSpec.PodGroupPolicy)
-}
-
 func jobsetApplyToJobset(jobsetApply *jobsetapplyapi.JobSetApplyConfiguration) (*jobsetapi.JobSet, error) {
 	jsonData, err := json.Marshal(jobsetApply)
 	if err != nil {
diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go
index 52a4794d2..0fe2daffc 100644
--- a/pkg/features/kube_features.go
+++ b/pkg/features/kube_features.go
@@ -164,6 +164,13 @@ const (
 	// This feature gate is going to be replaced by an API before graduation or deprecation.
 	FlavorFungibilityImplicitPreferenceDefault featuregate.Feature = "FlavorFungibilityImplicitPreferenceDefault"
 
+	// owner: @pajakd
+	// kep: https://github.com/kubernetes-sigs/kueue/tree/main/keps/2724-topology-aware-scheduling
+	//
+	// Use balanced placement algorithm in TAS. This feature gate is going to be replaced by an API
+	// before graduation or deprecation.
+	TASBalancedPlacement featuregate.Feature = "TASBalancedPlacement"
+
 	// owner: @alaypatel07
 	// kep: https://github.com/kubernetes-sigs/kueue/tree/main/keps/2941-DRA
 	//
@@ -298,6 +305,9 @@ var defaultVersionedFeatureGates = map[featuregate.Feature]featuregate.Versioned
 	FlavorFungibilityImplicitPreferenceDefault: {
 		{Version: version.MustParse("0.13"), Default: false, PreRelease: featuregate.Alpha},
 	},
+	TASBalancedPlacement: {
+		{Version: version.MustParse("0.15"), Default: false, PreRelease: featuregate.Alpha},
+	},
 	DynamicResourceAllocation: {
 		{Version: version.MustParse("0.14"), Default: false, PreRelease: featuregate.Alpha},
 	},
diff --git a/pkg/scheduler/flavorassigner/tas_flavorassigner.go b/pkg/scheduler/flavorassigner/tas_flavorassigner.go
index dd96bb588..957207476 100644
--- a/pkg/scheduler/flavorassigner/tas_flavorassigner.go
+++ b/pkg/scheduler/flavorassigner/tas_flavorassigner.go
@@ -77,9 +77,9 @@ func podSetTopologyRequest(psAssignment *PodSetAssignment,
 	if err != nil {
 		return nil, err
 	}
-	if !workload.HasQuotaReservation(wl.Obj) && cq.HasProvRequestAdmissionCheck(*tasFlvr) {
-		// We delay TAS as this is the first scheduling pass, and there is a
-		// ProvisioningRequest admission check used for the flavor.
+	if cq.HasMultiKueueAdmissionCheck() || (!workload.HasQuotaReservation(wl.Obj) && cq.HasProvRequestAdmissionCheck(*tasFlvr)) {
+		// Delay TAS when MultiKueue is used (topology always assigned on worker cluster).
+		// For ProvisioningRequest, delay TAS on first scheduling pass only (topology assigned after provisioning).
 		psAssignment.DelayedTopologyRequest = ptr.To(kueue.DelayedTopologyRequestStatePending)
 		return nil, nil
 	}
diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go
index f2ab75e6a..d7c8cae84 100644
--- a/pkg/scheduler/scheduler.go
+++ b/pkg/scheduler/scheduler.go
@@ -807,9 +807,10 @@ func (s *Scheduler) recordQuotaReservationMetrics(newWorkload, originalWorkload
 
 	s.recorder.Eventf(newWorkload, corev1.EventTypeNormal, "QuotaReserved", "Quota reserved in ClusterQueue %v, wait time since queued was %.0fs", admission.ClusterQueue, waitTime.Seconds())
 
-	metrics.QuotaReservedWorkload(admission.ClusterQueue, newWorkload.Spec.PriorityClassName, waitTime)
+	priorityClassName := workload.PriorityClassName(newWorkload)
+	metrics.QuotaReservedWorkload(admission.ClusterQueue, priorityClassName, waitTime)
 	if features.Enabled(features.LocalQueueMetrics) {
-		metrics.LocalQueueQuotaReservedWorkload(metrics.LQRefFromWorkload(newWorkload), newWorkload.Spec.PriorityClassName, waitTime)
+		metrics.LocalQueueQuotaReservedWorkload(metrics.LQRefFromWorkload(newWorkload), priorityClassName, waitTime)
 	}
 }
 
@@ -820,20 +821,17 @@ func (s *Scheduler) recordWorkloadAdmissionEvents(newWorkload, originalWorkload
 	}
 
 	s.recorder.Eventf(newWorkload, corev1.EventTypeNormal, "Admitted", "Admitted by ClusterQueue %v, wait time since reservation was 0s", admission.ClusterQueue)
-	metrics.AdmittedWorkload(admission.ClusterQueue, newWorkload.Spec.PriorityClassName, waitTime)
 
+	priorityClassName := workload.PriorityClassName(newWorkload)
+	metrics.AdmittedWorkload(admission.ClusterQueue, priorityClassName, waitTime)
 	if features.Enabled(features.LocalQueueMetrics) {
-		metrics.LocalQueueAdmittedWorkload(
-			metrics.LQRefFromWorkload(newWorkload),
-			newWorkload.Spec.PriorityClassName,
-			waitTime,
-		)
+		metrics.LocalQueueAdmittedWorkload(metrics.LQRefFromWorkload(newWorkload), priorityClassName, waitTime)
 	}
 
 	if len(newWorkload.Status.AdmissionChecks) > 0 {
-		metrics.ReportAdmissionChecksWaitTime(admission.ClusterQueue, newWorkload.Spec.PriorityClassName, 0)
+		metrics.ReportAdmissionChecksWaitTime(admission.ClusterQueue, priorityClassName, 0)
 		if features.Enabled(features.LocalQueueMetrics) {
-			metrics.ReportLocalQueueAdmissionChecksWaitTime(metrics.LQRefFromWorkload(newWorkload), newWorkload.Spec.PriorityClassName, 0)
+			metrics.ReportLocalQueueAdmissionChecksWaitTime(metrics.LQRefFromWorkload(newWorkload), priorityClassName, 0)
 		}
 	}
 }
diff --git a/pkg/util/priority/priority.go b/pkg/util/priority/priority.go
index 060d896d8..ee4894c3b 100644
--- a/pkg/util/priority/priority.go
+++ b/pkg/util/priority/priority.go
@@ -30,51 +30,49 @@ import (
 
 // Priority returns priority of the given workload.
 func Priority(w *kueue.Workload) int32 {
-	// When priority of a running workload is nil, it means it was created at a time
+	// When the priority of a running workload is nil, it means it was created at a time
 	// that there was no global default priority class and the priority class
 	// name of the pod was empty. So, we resolve to the static default priority.
 	return ptr.Deref(w.Spec.Priority, constants.DefaultPriority)
 }
 
 // GetPriorityFromPriorityClass returns the priority populated from
-// priority class. If not specified, priority will be default or
+// priority class. If not specified, the priority will be default or
 // zero if there is no default.
-func GetPriorityFromPriorityClass(ctx context.Context, client client.Client,
-	priorityClass string) (string, string, int32, error) {
+func GetPriorityFromPriorityClass(ctx context.Context, client client.Client, priorityClass string) (*kueue.PriorityClassRef, int32, error) {
 	if len(priorityClass) == 0 {
 		return getDefaultPriority(ctx, client)
 	}
 
 	pc := &schedulingv1.PriorityClass{}
 	if err := client.Get(ctx, types.NamespacedName{Name: priorityClass}, pc); err != nil {
-		return "", "", 0, err
+		return nil, 0, err
 	}
 
-	return pc.Name, constants.PodPriorityClassSource, pc.Value, nil
+	return kueue.NewPodPriorityClassRef(pc.Name), pc.Value, nil
 }
 
 // GetPriorityFromWorkloadPriorityClass returns the priority populated from
 // workload priority class. If not specified, returns 0.
 // DefaultPriority is not called within this function
-// because k8s priority class should be  checked next.
-func GetPriorityFromWorkloadPriorityClass(ctx context.Context, client client.Client,
-	workloadPriorityClass string) (string, string, int32, error) {
+// because k8s priority class should be checked next.
+func GetPriorityFromWorkloadPriorityClass(ctx context.Context, client client.Client, workloadPriorityClass string) (*kueue.PriorityClassRef, int32, error) {
 	wpc := &kueue.WorkloadPriorityClass{}
 	if err := client.Get(ctx, types.NamespacedName{Name: workloadPriorityClass}, wpc); err != nil {
-		return "", "", 0, err
+		return nil, 0, err
 	}
-	return wpc.Name, constants.WorkloadPriorityClassSource, wpc.Value, nil
+	return kueue.NewWorkloadPriorityClassRef(wpc.Name), wpc.Value, nil
 }
 
-func getDefaultPriority(ctx context.Context, client client.Client) (string, string, int32, error) {
+func getDefaultPriority(ctx context.Context, client client.Client) (*kueue.PriorityClassRef, int32, error) {
 	dpc, err := getDefaultPriorityClass(ctx, client)
 	if err != nil {
-		return "", "", 0, err
+		return nil, 0, err
 	}
 	if dpc != nil {
-		return dpc.Name, constants.PodPriorityClassSource, dpc.Value, nil
+		return kueue.NewPodPriorityClassRef(dpc.Name), dpc.Value, nil
 	}
-	return "", "", int32(constants.DefaultPriority), nil
+	return nil, constants.DefaultPriority, nil
 }
 
 func getDefaultPriorityClass(ctx context.Context, client client.Client) (*schedulingv1.PriorityClass, error) {
diff --git a/pkg/workload/workload.go b/pkg/workload/workload.go
index 5ef39aa89..4375b16db 100644
--- a/pkg/workload/workload.go
+++ b/pkg/workload/workload.go
@@ -819,6 +819,18 @@ func SetEvictedCondition(w *kueue.Workload, now time.Time, reason string, messag
 	return apimeta.SetStatusCondition(&w.Status.Conditions, condition)
 }
 
+func SetFinishedCondition(w *kueue.Workload, now time.Time, reason string, message string) bool {
+	condition := metav1.Condition{
+		Type:               kueue.WorkloadFinished,
+		Status:             metav1.ConditionTrue,
+		LastTransitionTime: metav1.NewTime(now),
+		Reason:             reason,
+		Message:            api.TruncateConditionMessage(message),
+		ObservedGeneration: w.Generation,
+	}
+	return apimeta.SetStatusCondition(&w.Status.Conditions, condition)
+}
+
 // PropagateResourceRequests synchronizes w.Status.ResourceRequests to
 // with info.TotalRequests if the feature gate is enabled and returns true if w was updated
 func PropagateResourceRequests(w *kueue.Workload, info *Info) bool {
@@ -1296,11 +1308,38 @@ func Evict(ctx context.Context, c client.Client, recorder record.EventRecorder,
 	}
 	reportEvictedWorkload(recorder, wl, wl.Status.Admission.ClusterQueue, reason, msg, underlyingCause)
 	if reportWorkloadEvictedOnce {
-		metrics.ReportEvictedWorkloadsOnce(wl.Status.Admission.ClusterQueue, reason, string(underlyingCause), wl.Spec.PriorityClassName)
+		metrics.ReportEvictedWorkloadsOnce(wl.Status.Admission.ClusterQueue, reason, string(underlyingCause), PriorityClassName(wl))
 	}
 	return nil
 }
 
+func Finish(ctx context.Context, c client.Client, wl *kueue.Workload, reason, msg, managerPrefix string, clock clock.Clock) error {
+	if features.Enabled(features.WorkloadRequestUseMergePatch) {
+		return clientutil.PatchStatus(ctx, c, wl, func() (client.Object, bool, error) {
+			update := SetFinishedCondition(wl, clock.Now(), reason, msg)
+			return wl, update, nil
+		})
+	} else {
+		newWl := BaseSSAWorkload(wl, true)
+		SetFinishedCondition(newWl, clock.Now(), reason, msg)
+		fieldOwner := client.FieldOwner(managerPrefix + "-" + kueue.WorkloadFinished)
+		return c.Status().Patch(ctx, newWl, client.Apply, fieldOwner, client.ForceOwnership)
+	}
+}
+
+func PriorityClassName(wl *kueue.Workload) string {
+	if wl.Spec.PriorityClassRef != nil {
+		return wl.Spec.PriorityClassRef.Name
+	}
+	return ""
+}
+
+func IsWorkloadPriorityClass(wl *kueue.Workload) bool {
+	return wl.Spec.PriorityClassRef != nil &&
+		wl.Spec.PriorityClassRef.Kind == kueue.WorkloadPriorityClassKind &&
+		wl.Spec.PriorityClassRef.Group == kueue.WorkloadPriorityClassGroup
+}
+
 func prepareForEviction(w *kueue.Workload, now time.Time, reason, message string) {
 	SetEvictedCondition(w, now, reason, message)
 	resetClusterNomination(w)
@@ -1318,7 +1357,8 @@ func resetUnhealthyNodes(w *kueue.Workload) {
 }
 
 func reportEvictedWorkload(recorder record.EventRecorder, wl *kueue.Workload, cqName kueue.ClusterQueueReference, reason, message string, underlyingCause kueue.EvictionUnderlyingCause) {
-	metrics.ReportEvictedWorkloads(cqName, reason, string(underlyingCause), wl.Spec.PriorityClassName)
+	priorityClassName := PriorityClassName(wl)
+	metrics.ReportEvictedWorkloads(cqName, reason, string(underlyingCause), priorityClassName)
 	if podsReadyToEvictionTime := workloadsWithPodsReadyToEvictedTime(wl); podsReadyToEvictionTime != nil {
 		metrics.PodsReadyToEvictedTimeSeconds.WithLabelValues(string(cqName), reason, string(underlyingCause)).Observe(podsReadyToEvictionTime.Seconds())
 	}
@@ -1327,7 +1367,7 @@ func reportEvictedWorkload(recorder record.EventRecorder, wl *kueue.Workload, cq
 			metrics.LQRefFromWorkload(wl),
 			reason,
 			string(underlyingCause),
-			wl.Spec.PriorityClassName,
+			priorityClassName,
 		)
 	}
 	eventReason := ReasonWithCause(kueue.WorkloadEvicted, reason)
diff --git a/pkg/workloadslicing/workloadslicing.go b/pkg/workloadslicing/workloadslicing.go
index f5b2a4b19..268b7406b 100644
--- a/pkg/workloadslicing/workloadslicing.go
+++ b/pkg/workloadslicing/workloadslicing.go
@@ -104,15 +104,7 @@ func Finish(ctx context.Context, clnt client.Client, clk clock.Clock, workloadSl
 	if apimeta.IsStatusConditionTrue(workloadSlice.Status.Conditions, kueue.WorkloadFinished) {
 		return nil
 	}
-	if err := clientutil.PatchStatus(ctx, clnt, workloadSlice, func() (client.Object, bool, error) {
-		return workloadSlice, apimeta.SetStatusCondition(&workloadSlice.Status.Conditions, metav1.Condition{
-			Type:               kueue.WorkloadFinished,
-			Status:             metav1.ConditionTrue,
-			Reason:             reason,
-			Message:            message,
-			LastTransitionTime: metav1.NewTime(clk.Now()),
-		}), nil
-	}); err != nil {
+	if err := workload.Finish(ctx, clnt, workloadSlice, reason, message, "", clk); err != nil {
 		return fmt.Errorf("failed to patch workload slice status: %w", err)
 	}
 	return nil
diff --git a/site/content/en/docs/concepts/topology_aware_scheduling.md b/site/content/en/docs/concepts/topology_aware_scheduling.md
index f697f1433..3cc0f930f 100644
--- a/site/content/en/docs/concepts/topology_aware_scheduling.md
+++ b/site/content/en/docs/concepts/topology_aware_scheduling.md
@@ -239,6 +239,34 @@ The following table summarizes the behavior based on the combination of the feat
 
 We recommend keeping all three feature gates enabled to ensure the fastest feedback loop for workloads affected by node failures.
 
+#### Balanced Placement
+{{< feature-state state="alpha" for_version="v0.15" >}}
+{{% alert title="Note" color="primary" %}}
+`TASBalancedPlacement` is currently an alpha feature and is disabled by default.
+
+You can enable it by editing the `TASBalancedPlacement` feature gate. Refer to the
+[Installation guide](/docs/installation/#change-the-feature-gates-configuration)
+for instructions on configuring feature gates.
+{{% /alert %}}
+
+The balanced placement algorithm provides an alternative to the greedy packing strategies. Instead of
+iterating over the domains sorted from largest to smallest available space (or based on some other criteria)
+and trying to pack as many pods/slices as possible to each domain until the request fits, it first finds the
+optimal set of domains that fit the request and then distributes the pods/slices as evenly as possible across
+these domains.
+
+Greedy placement strategies (such as `BestFit` and `LeastFreeCapacity`) might result in a placement with a small
+number of pods assigned to the last considered domain. For example 12 pods distributed among domains with
+capacities (10,10) will be placed (10,2). However, in some applications, a more balanced placement (6,6) would
+be more efficient. Some examples of such cases would be all-to-all communication procedures (e.g. Allgather)
+since more balanced placement leads to more efficient cross-domain traffic.
+
+To use this feature, use the `kueue.x-k8s.io/podset-preferred-topology` annotation on the Job. Kueue TAS makes 
+sure that the minimum number of pods (or slices) placed on any domain **one level below** the indicated level
+will be maximied. Also (as a second criterion) the number of domains used on the indicated level will be
+minimized. However, if the Job would not fit within a single domain **one level above** the indicated level,
+Kueue will not perform the balanced placement and will fallback to the standard TAS algorithm.
+
 ### Limitations
 
 Currently, there are limitations for the compatibility of TAS with other
diff --git a/site/content/en/docs/reference/kueue.v1beta2.md b/site/content/en/docs/reference/kueue.v1beta2.md
index dc6b1ef17..4a061fcd5 100644
--- a/site/content/en/docs/reference/kueue.v1beta2.md
+++ b/site/content/en/docs/reference/kueue.v1beta2.md
@@ -2200,6 +2200,82 @@ result in failure during workload admission.</p>
 
 
 
+## `PriorityClassGroup`     {#kueue-x-k8s-io-v1beta2-PriorityClassGroup}
+    
+(Alias of `string`)
+
+**Appears in:**
+
+- [PriorityClassRef](#kueue-x-k8s-io-v1beta2-PriorityClassRef)
+
+
+<p>PriorityClassGroup indicates the API group of the PriorityClass object.</p>
+
+
+
+
+## `PriorityClassKind`     {#kueue-x-k8s-io-v1beta2-PriorityClassKind}
+    
+(Alias of `string`)
+
+**Appears in:**
+
+- [PriorityClassRef](#kueue-x-k8s-io-v1beta2-PriorityClassRef)
+
+
+<p>PriorityClassKind is the kind of the PriorityClass object.</p>
+
+
+
+
+## `PriorityClassRef`     {#kueue-x-k8s-io-v1beta2-PriorityClassRef}
+    
+
+**Appears in:**
+
+- [WorkloadSpec](#kueue-x-k8s-io-v1beta2-WorkloadSpec)
+
+
+<p>PriorityClassRef references a PriorityClass in a specific API group.</p>
+
+
+<table class="table">
+<thead><tr><th width="30%">Field</th><th>Description</th></tr></thead>
+<tbody>
+    
+  
+<tr><td><code>group</code> <B>[Required]</B><br/>
+<a href="#kueue-x-k8s-io-v1beta2-PriorityClassGroup"><code>PriorityClassGroup</code></a>
+</td>
+<td>
+   <p>group is the API group of the PriorityClass object.
+Use &quot;kueue.x-k8s.io&quot; for WorkloadPriorityClass.
+Use &quot;scheduling.k8s.io&quot; for Pod PriorityClass.</p>
+</td>
+</tr>
+<tr><td><code>kind</code> <B>[Required]</B><br/>
+<a href="#kueue-x-k8s-io-v1beta2-PriorityClassKind"><code>PriorityClassKind</code></a>
+</td>
+<td>
+   <p>kind is the kind of the PriorityClass object.</p>
+</td>
+</tr>
+<tr><td><code>name</code> <B>[Required]</B><br/>
+<code>string</code>
+</td>
+<td>
+   <p>name is the name of the PriorityClass the Workload is associated with.
+If specified, indicates the workload's priority.
+&quot;system-node-critical&quot; and &quot;system-cluster-critical&quot; are two special
+keywords which indicate the highest priorities with the former being
+the highest priority. Any other name must be defined by creating a
+PriorityClass object with that name. If not specified, the workload
+priority will be default or zero if there is no default.</p>
+</td>
+</tr>
+</tbody>
+</table>
+
 ## `ProvisioningRequestConfigPodSetMergePolicy`     {#kueue-x-k8s-io-v1beta2-ProvisioningRequestConfigPodSetMergePolicy}
     
 (Alias of `string`)
@@ -2998,17 +3074,11 @@ podSets cannot be changed.</p>
 queueName cannot be changed while .status.admission is not null.</p>
 </td>
 </tr>
-<tr><td><code>priorityClassName</code><br/>
-<code>string</code>
+<tr><td><code>priorityClassRef</code><br/>
+<a href="#kueue-x-k8s-io-v1beta2-PriorityClassRef"><code>PriorityClassRef</code></a>
 </td>
 <td>
-   <p>priorityClassName is the name of the PriorityClass the Workload is associated with.
-If specified, indicates the workload's priority.
-&quot;system-node-critical&quot; and &quot;system-cluster-critical&quot; are two special
-keywords which indicate the highest priorities with the former being
-the highest priority. Any other name must be defined by creating a
-PriorityClass object with that name. If not specified, the workload
-priority will be default or zero if there is no default.</p>
+   <p>priorityClassRef references a PriorityClass object that defines the workload's priority.</p>
 </td>
 </tr>
 <tr><td><code>priority</code><br/>
@@ -3017,18 +3087,9 @@ priority will be default or zero if there is no default.</p>
 <td>
    <p>priority determines the order of access to the resources managed by the
 ClusterQueue where the workload is queued.
-The priority value is populated from PriorityClassName.
+The priority value is populated from the referenced PriorityClass (via priorityClassRef).
 The higher the value, the higher the priority.
-If priorityClassName is specified, priority must not be null.</p>
-</td>
-</tr>
-<tr><td><code>priorityClassSource</code><br/>
-<code>string</code>
-</td>
-<td>
-   <p>priorityClassSource determines whether the priorityClass field refers to a pod PriorityClass or kueue.x-k8s.io/workloadpriorityclass.
-Workload's PriorityClass can accept the name of a pod priorityClass or a workloadPriorityClass.
-When using pod PriorityClass, a priorityClassSource field has the scheduling.k8s.io/priorityclass value.</p>
+If priorityClassRef is specified, priority must not be null.</p>
 </td>
 </tr>
 <tr><td><code>active</code> <B>[Required]</B><br/>
diff --git a/site/content/en/docs/tasks/_index.md b/site/content/en/docs/tasks/_index.md
index f2d62f98e..52c2d8b0d 100755
--- a/site/content/en/docs/tasks/_index.md
+++ b/site/content/en/docs/tasks/_index.md
@@ -36,7 +36,9 @@ batch user is a researcher, AI/ML engineer, data scientist, among others.
 
 As a batch user, you can learn how to:
 - [Run a Kueue managed batch/Job](run/jobs).
-- [Run a Kueue managed Kubeflow Job](run/kubeflow).
+- [Run a Kueue managed Kubeflow TrainJob (v2)](run/trainjobs).
+  Kueue supports Kubeflow Trainer v2's unified TrainJob API.
+- [Run a Kueue managed Kubeflow Job (v1)](run/kubeflow).
   Kueue supports MPIJob v2beta1, PyTorchJob, TFJob, XGBoostJob and PaddleJob.
 - [Run a Kueue managed KubeRay RayJob](run/rayjobs).
 - [Run a Kueue managed KubeRay RayCluster](run/rayclusters).
diff --git a/site/content/en/docs/tasks/run/kubeflow/_index.md b/site/content/en/docs/tasks/run/kubeflow/_index.md
index bf6cea017..23916cd65 100755
--- a/site/content/en/docs/tasks/run/kubeflow/_index.md
+++ b/site/content/en/docs/tasks/run/kubeflow/_index.md
@@ -1,27 +1,25 @@
 ---
-
-title: "Run with Kubeflow"
-linkTitle: "Kubeflow Jobs"
-weight: 6
+title: "Kubeflow Jobs (v1)"
+linkTitle: "Kubeflow Jobs (v1)"
+weight: 7
 date: 2023-08-23
 description: >
-  How to run Kueue with Kubeflow
+  Run Kueue managed Kubeflow Trainer v1 Jobs
 no_list: true
 ---
 
-The tasks below show you how to run Kueue managed Kubeflow Jobs.
-
-### [MPI Operator](https://github.com/kubeflow/mpi-operator) Integration
-- [Run a Kueue managed Kubeflow MPIJob](/docs/tasks/run_kubeflow_jobs/run_mpijobs).
-
-### [Trainer](https://github.com/kubeflow/trainer) Integration
+The tasks below show you how to run Kueue managed Kubeflow Trainer v1 Jobs.
 
 {{% alert title="Note" color="primary" %}}
-Kueue supports only traditional Jobs served until Trainer v1.9.x and does not support new TrainJob. 
+**Kubeflow Trainer v2 is now available:** Consider using [TrainJob](/docs/tasks/run/trainjobs/) which provides a unified API for all training frameworks. Trainer v1 APIs (PyTorchJob, TFJob, etc.) are stable and production-ready.
 {{% /alert %}}
 
-- [Run a Kueue managed Kubeflow PyTorchJob](/docs/tasks/run_kubeflow_jobs/run_pytorchjobs).
-- [Run a Kueue managed Kubeflow TFJob](/docs/tasks/run_kubeflow_jobs/run_tfjobs).
-- [Run a Kueue managed Kubeflow XGBoostJob](/docs/tasks/run_kubeflow_jobs/run_xgboostjobs).
-- [Run a Kueue managed kubeflow PaddleJob](/docs/tasks/run_kubeflow_jobs/run_paddlejobs).
-- [Run a Kueue managed kubeflow JAXJob](/docs/tasks/run_kubeflow_jobs/run_jaxjobs).
+### [Trainer v1](https://github.com/kubeflow/trainer) Integration
+- [Run a Kueue managed Kubeflow PyTorchJob](/docs/tasks/run/kubeflow/pytorchjobs/).
+- [Run a Kueue managed Kubeflow TFJob](/docs/tasks/run/kubeflow/tfjobs/).
+- [Run a Kueue managed Kubeflow XGBoostJob](/docs/tasks/run/kubeflow/xgboostjobs/).
+- [Run a Kueue managed Kubeflow PaddleJob](/docs/tasks/run/kubeflow/paddlejobs/).
+- [Run a Kueue managed Kubeflow JAXJob](/docs/tasks/run/kubeflow/jaxjobs/).
+
+### [MPI Operator](https://github.com/kubeflow/mpi-operator) Integration
+- [Run a Kueue managed Kubeflow MPIJob](/docs/tasks/run/kubeflow/mpijobs/).
diff --git a/site/content/en/docs/tasks/run/multikueue/job.md b/site/content/en/docs/tasks/run/multikueue/job.md
index a1a7e7f8e..1b10ba35a 100644
--- a/site/content/en/docs/tasks/run/multikueue/job.md
+++ b/site/content/en/docs/tasks/run/multikueue/job.md
@@ -13,11 +13,7 @@ Check the [MultiKueue installation guide](/docs/tasks/manage/setup_multikueue) o
 
 For the ease of setup and use we recommend using at least Kueue v0.8.1.
 
-The recommended way of running MultiKueue depends on the configuration of the `JobManagedBy` feature gate in your cluster. 
-
-{{% alert title="Note" color="primary" %}}
-The `JobManagedBy` feature gate is disabled in 1.30 and 1.31 by default, and will be enabled in 1.32 by default.
-{{% /alert %}}
+The recommended way of running MultiKueue depends on the configuration of the `JobManagedBy` feature gate in your cluster.
 
 ### Cluster with JobManagedBy enabled
 
diff --git a/site/content/en/docs/tasks/run/multikueue/kubeflow.md b/site/content/en/docs/tasks/run/multikueue/kubeflow.md
index 9f8884cca..60e3c8a9f 100644
--- a/site/content/en/docs/tasks/run/multikueue/kubeflow.md
+++ b/site/content/en/docs/tasks/run/multikueue/kubeflow.md
@@ -1,12 +1,18 @@
----
-title: "Run Kubeflow Jobs in Multi-Cluster"
-linkTitle: "Kubeflow"
+ ---
+title: "Run Kubeflow Jobs (v1) in Multi-Cluster"
+linkTitle: "Kubeflow (v1)"
 weight: 4
 date: 2024-09-25
 description: >
-  Run a MultiKueue scheduled Kubeflow Jobs.
+  Run MultiKueue scheduled Kubeflow Trainer v1 Jobs (PyTorchJob, TFJob, etc.).
 ---
 
+{{% alert title="Note" color="primary" %}}
+This page covers legacy Kubeflow Trainer v1 jobs (PyTorchJob, TFJob, XGBoostJob, etc.). 
+
+For Kubeflow Trainer v2 TrainJob, see [Run TrainJobs in Multi-Cluster](/docs/tasks/run/multikueue/trainjob/).
+{{% /alert %}}
+
 ## Before you begin
 
 Check the [MultiKueue installation guide](/docs/tasks/manage/setup_multikueue) on how to properly setup MultiKueue clusters.
diff --git a/site/content/en/docs/tasks/run/multikueue/trainjob.md b/site/content/en/docs/tasks/run/multikueue/trainjob.md
new file mode 100644
index 000000000..bf4a452e4
--- /dev/null
+++ b/site/content/en/docs/tasks/run/multikueue/trainjob.md
@@ -0,0 +1,103 @@
+---
+title: "Run TrainJobs in Multi-Cluster"
+linkTitle: "TrainJob"
+weight: 3
+date: 2025-11-06
+description: >
+  Run a MultiKueue scheduled TrainJob from Kubeflow Trainer v2.
+---
+
+## Before you begin
+
+Check the [MultiKueue installation guide](/docs/tasks/manage/setup_multikueue) on how to properly setup MultiKueue clusters.
+
+For the ease of setup and use we recommend using at least Kueue v0.11.0 and for Kubeflow Trainer at least v2.0.0.
+
+See [Trainer Installation](https://www.kubeflow.org/docs/components/trainer/operator-guides/installation/) for installation and configuration details of Kubeflow Trainer v2.
+
+{{% alert title="Note" color="primary" %}}
+TrainJob is part of Kubeflow Trainer v2, which introduces a unified API for all training frameworks. It replaces the framework-specific job types (PyTorchJob, TFJob, etc.) from Trainer v1.
+
+For legacy Kubeflow Jobs (v1), see [Run Kubeflow Jobs in Multi-Cluster](/docs/tasks/run/multikueue/kubeflow/).
+{{% /alert %}}
+
+## MultiKueue integration
+
+Once the setup is complete you can test it by running a TrainJob [`sample-trainjob`](/docs/tasks/run/trainjobs/#using-clustertrainingruntime). 
+
+{{% alert title="Note" color="primary" %}}
+Kueue defaults the `spec.managedBy` field to `kueue.x-k8s.io/multikueue` on the management cluster for TrainJob. 
+
+This allows the Trainer to ignore the Jobs managed by MultiKueue on the management cluster, and in particular skip Pod creation. 
+
+The pods are created and the actual computation will happen on the mirror copy of the TrainJob on the selected worker cluster. 
+The mirror copy of the TrainJob does not have the field set.
+{{% /alert %}}
+
+## ClusterTrainingRuntime and TrainingRuntime
+
+TrainJobs in MultiKueue environments work with both ClusterTrainingRuntime and TrainingRuntime:
+
+- **ClusterTrainingRuntime**: Must be installed on all worker clusters. The runtime definition should be consistent across clusters.
+- **TrainingRuntime**: Must be installed in the corresponding namespaces on the worker clusters where TrainJobs will run.
+
+Ensure that the runtime configurations referenced by your TrainJobs are available on the target worker clusters before dispatching the jobs.
+
+## Example
+
+Here's a complete example of running a TrainJob with MultiKueue:
+
+1. **Create a ClusterTrainingRuntime** on all clusters (management and workers):
+
+```yaml
+apiVersion: trainer.kubeflow.org/v1alpha1
+kind: ClusterTrainingRuntime
+metadata:
+  name: torch-distributed
+  labels:
+    trainer.kubeflow.org/framework: torch
+spec:
+  mlPolicy:
+    numNodes: 1
+    torch:
+      numProcPerNode: auto
+  template:
+    spec:
+      replicatedJobs:
+        - name: node
+          template:
+            metadata:
+              labels:
+                trainer.kubeflow.org/trainjob-ancestor-step: trainer
+            spec:
+              template:
+                spec:
+                  containers:
+                    - name: node
+                      image: pytorch/pytorch:2.7.1-cuda12.8-cudnn9-runtime
+```
+
+2. **Create a MultiKueue-enabled TrainJob** on the management cluster:
+
+```yaml
+apiVersion: trainer.kubeflow.org/v1alpha1
+kind: TrainJob
+metadata:
+  name: pytorch-multikueue
+  namespace: default
+  labels:
+    kueue.x-k8s.io/queue-name: multikueue-queue
+spec:
+  runtimeRef:
+    name: torch-distributed
+    kind: ClusterTrainingRuntime
+  trainer:
+    numNodes: 2
+    resourcesPerNode:
+      requests:
+        cpu: "4"
+        memory: "8Gi"
+        nvidia.com/gpu: "1"
+```
+
+The TrainJob will be dispatched to a worker cluster based on the MultiKueue configuration and available resources. The training pods will be created and executed on the selected worker cluster.
diff --git a/site/content/en/docs/tasks/run/trainjobs.md b/site/content/en/docs/tasks/run/trainjobs.md
new file mode 100644
index 000000000..5484b15c6
--- /dev/null
+++ b/site/content/en/docs/tasks/run/trainjobs.md
@@ -0,0 +1,254 @@
+---
+title: "Run A TrainJob"
+linkTitle: "TrainJobs"
+date: 2024-11-05
+weight: 6
+description: >
+  Run a Kueue scheduled TrainJob from Kubeflow Trainer v2
+---
+
+This page shows how to leverage Kueue's scheduling and resource management capabilities when running [Kubeflow Trainer](https://www.kubeflow.org/docs/components/trainer/) TrainJobs.
+
+Kubeflow Trainer v2 introduces the `TrainJob` API that works seamlessly with Kueue for batch scheduling and resource management. TrainJobs can be configured to use either:
+
+- **ClusterTrainingRuntime**: Cluster-scoped training runtimes that can be used across all namespaces
+- **TrainingRuntime**: Namespace-scoped training runtimes that are only available within a specific namespace
+
+Kueue manages TrainJobs by scheduling their underlying jobs according to available quota and priority.
+
+This guide is for [batch users](/docs/tasks#batch-user) that have a basic understanding of Kueue. For more information, see [Kueue's overview](/docs/overview).
+
+## Before you begin
+
+1. Check [administer cluster quotas](/docs/tasks/manage/administer_cluster_quotas) for details on the initial cluster setup.
+
+2. Install Kubeflow Trainer v2. Check [the Trainer installation guide](https://www.kubeflow.org/docs/components/trainer/operator-guides/installation/).
+
+   **Note**: The minimum required Trainer version is v2.0.0.
+
+3. Enable TrainJob integration in Kueue. You can [modify kueue configurations from installed releases](/docs/installation#install-a-custom-configured-released-version) to include TrainJobs as an allowed workload.
+
+## TrainJob definition
+
+### a. Queue selection
+
+The target [local queue](/docs/concepts/local_queue) should be specified in the `metadata.labels` section of the TrainJob configuration:
+
+```yaml
+metadata:
+  labels:
+    kueue.x-k8s.io/queue-name: user-queue
+```
+
+### b. Suspend field
+
+By default, Kueue will set `suspend` to true via webhook and unsuspend it when the TrainJob is admitted:
+
+```yaml
+spec:
+  suspend: true
+```
+
+## Using ClusterTrainingRuntime
+
+ClusterTrainingRuntimes are cluster-scoped resources that define training configurations accessible across all namespaces. They are typically created by platform administrators. For more details on ClusterTrainingRuntime configuration, see the [Kubeflow Runtime Guide](https://www.kubeflow.org/docs/components/trainer/operator-guides/runtime/).
+
+### Example: PyTorch Distributed Training with ClusterTrainingRuntime
+
+First, create a ClusterTrainingRuntime for PyTorch distributed training:
+
+```yaml
+apiVersion: trainer.kubeflow.org/v1alpha1
+kind: ClusterTrainingRuntime
+metadata:
+  name: torch-distributed
+  labels:
+    trainer.kubeflow.org/framework: torch
+spec:
+  mlPolicy:
+    numNodes: 1
+    torch:
+      numProcPerNode: auto
+  template:
+    spec:
+      replicatedJobs:
+        - name: node
+          template:
+            metadata:
+              labels:
+                trainer.kubeflow.org/trainjob-ancestor-step: trainer
+            spec:
+              template:
+                spec:
+                  containers:
+                    - name: node
+                      image: pytorch/pytorch:2.7.1-cuda12.8-cudnn9-runtime
+```
+
+Now, create a TrainJob that references this ClusterTrainingRuntime and will be scheduled by Kueue:
+
+```yaml
+apiVersion: trainer.kubeflow.org/v1alpha1
+kind: TrainJob
+metadata:
+  name: pytorch-distributed
+  namespace: default
+  labels:
+    kueue.x-k8s.io/queue-name: user-queue
+spec:
+  runtimeRef:
+    name: torch-distributed
+    kind: ClusterTrainingRuntime
+  trainer:
+    numNodes: 2
+    resourcesPerNode:
+      requests:
+        cpu: "4"
+        memory: "8Gi"
+        nvidia.com/gpu: "1"
+```
+
+**Key Points:**
+- The `kueue.x-k8s.io/queue-name` label is the only Kueue-specific addition needed
+- The `runtimeRef` points to the `ClusterTrainingRuntime` named `torch-distributed`
+- This example uses the default executable image from the runtime definition
+- Kueue will manage the lifecycle and admission of this TrainJob based on available quota
+- For custom training code, see the [Kubeflow Trainer examples](https://github.com/kubeflow/trainer/tree/master/examples)
+
+## Using TrainingRuntime (Namespace-scoped)
+
+TrainingRuntimes are namespace-scoped resources that provide more granular control per namespace. They are useful when different teams need customized training configurations.
+
+### Example: Custom PyTorch Training with TrainingRuntime
+
+Create a namespace-scoped TrainingRuntime:
+
+```yaml
+apiVersion: trainer.kubeflow.org/v1alpha1
+kind: TrainingRuntime
+metadata:
+  name: torch-custom
+  namespace: team-a
+spec:
+  mlPolicy:
+    numNodes: 1
+    torch:
+      numProcPerNode: auto
+  template:
+    spec:
+      replicatedJobs:
+        - name: node
+          template:
+            metadata:
+              labels:
+                trainer.kubeflow.org/trainjob-ancestor-step: trainer
+            spec:
+              template:
+                spec:
+                  containers:
+                    - name: trainer
+                      image: pytorch/pytorch:2.7.1-cuda12.8-cudnn9-runtime
+                      env:
+                        - name: CUSTOM_ENV
+                          value: "team-a-value"
+```
+
+Create a TrainJob that uses this namespace-scoped runtime:
+
+```yaml
+apiVersion: trainer.kubeflow.org/v1alpha1
+kind: TrainJob
+metadata:
+  name: pytorch-custom
+  namespace: team-a
+  labels:
+    kueue.x-k8s.io/queue-name: team-a-queue
+spec:
+  runtimeRef:
+    name: torch-custom
+    kind: TrainingRuntime
+    apiGroup: trainer.kubeflow.org
+  trainer:
+    image: docker.io/team-a/custom-training:latest
+    numNodes: 1
+    resourcesPerNode:
+      requests:
+        cpu: "2"
+        memory: "4Gi"
+```
+
+**Key Points:**
+- The TrainingRuntime is created in the same namespace as the TrainJob (`team-a`)
+- The `runtimeRef` specifies `kind: TrainingRuntime` to use the namespace-scoped runtime
+- Each namespace can have its own customized runtimes with different configurations
+
+## Using Workload Priority
+
+To prioritize TrainJobs, use Kueue's workload priority classes. See [Run job with WorkloadPriority](/docs/tasks/manage/run_job_with_workload_priority) for details on configuring and using workload priority classes.
+
+TrainJobs use the same priority mechanism as other Kueue workloads via the `kueue.x-k8s.io/priority-class` label.
+
+## LLM Fine-Tuning with Kueue
+
+Kubeflow Trainer v2 supports LLM fine-tuning with TorchTune and DeepSpeed. For comprehensive examples, see:
+
+- [Fine-tune Llama-3.2-1B with Alpaca Dataset](https://github.com/kubeflow/trainer/blob/master/examples/torchtune/llama3_2/alpaca-trainjob-yaml.ipynb)
+- [Fine-tune Qwen2.5-1.5B with Alpaca Dataset](https://github.com/kubeflow/trainer/blob/master/examples/torchtune/qwen2_5/qwen2.5-1.5B-with-alpaca.ipynb)
+- [T5 Fine-Tuning with DeepSpeed](https://github.com/kubeflow/trainer/blob/master/examples/deepspeed/text-summarization/T5-Fine-Tuning.ipynb)
+
+To use Kueue scheduling with these examples, add the queue label to your TrainJob:
+
+```yaml
+metadata:
+  labels:
+    kueue.x-k8s.io/queue-name: gpu-queue  # Add this label for Kueue scheduling
+spec:
+  runtimeRef:
+    name: torchtune-llama3.2-1b
+    kind: ClusterTrainingRuntime
+  # ... rest of the TrainJob spec as shown in Kubeflow examples
+```
+
+## Differences from Kubeflow Training Operator V1
+
+{{% alert title="Important" color="warning" %}}
+Kubeflow Trainer v2 introduces a new API that is not compatible with Training Operator v1 APIs (PyTorchJob, TFJob, etc.). The key differences are:
+
+- **Unified API**: TrainJob replaces framework-specific CRDs like PyTorchJob, TFJob
+- **Runtime-based**: Training configurations are defined in reusable Runtimes
+- **Built on JobSet**: Uses Kubernetes JobSet as the underlying infrastructure
+- **Better integration**: Native support for Kueue scheduling from the start
+
+For migration guidance, refer to the [Kubeflow Trainer documentation](https://www.kubeflow.org/docs/components/trainer/operator-guides/migration/).
+{{% /alert %}}
+
+## Best Practices
+
+1. **Use ClusterTrainingRuntimes for common patterns**: Create cluster-scoped runtimes for frequently used training configurations
+2. **Use TrainingRuntimes for team-specific needs**: Leverage namespace-scoped runtimes for customizations per team
+3. **Set appropriate resource requests**: Ensure your TrainJob resource requests match the ResourceFlavor in your ClusterQueue
+4. **Monitor quota usage**: Use `kubectl get clusterqueue` to track resource utilization
+5. **Use priority classes**: Assign priorities to TrainJobs to ensure critical workloads are scheduled first
+6. **Test with small configurations**: Before scaling up, test your TrainJob configuration with minimal resources
+
+## Additional Resources
+
+- [Kubeflow Trainer Documentation](https://www.kubeflow.org/docs/components/trainer/)
+- [Kubeflow Runtime Guide](https://www.kubeflow.org/docs/components/trainer/operator-guides/runtime/)
+- [Fine-tune LLMs with TorchTune](https://www.kubeflow.org/docs/components/trainer/user-guides/builtin-trainer/torchtune/)
+- [Kueue Concepts](/docs/concepts/)
+- [Run job with WorkloadPriority](/docs/tasks/manage/run_job_with_workload_priority)
+- [Monitor Pending Workloads](/docs/tasks/manage/monitor_pending_workloads)
+- [Troubleshooting](/docs/tasks/troubleshooting)
+- [Kubeflow Python SDK](https://github.com/kubeflow/sdk/)
+
+## Troubleshooting
+
+For general troubleshooting guidance, see the [Kueue troubleshooting guide](/docs/tasks/troubleshooting).
+
+For TrainJob-specific issues, verify that the referenced ClusterTrainingRuntime or TrainingRuntime exists:
+
+```bash
+kubectl get clustertrainingruntime
+kubectl get trainingruntime -n <namespace>
+```
diff --git a/site/content/zh-CN/docs/tasks/run/multikueue/job.md b/site/content/zh-CN/docs/tasks/run/multikueue/job.md
index ac40d8d67..1b228b1b7 100644
--- a/site/content/zh-CN/docs/tasks/run/multikueue/job.md
+++ b/site/content/zh-CN/docs/tasks/run/multikueue/job.md
@@ -14,10 +14,6 @@ description: 运行 MultiKueue 调度的 Kubernetes Job。
 
 运行 MultiKueue 的推荐方式取决于集群中 `JobManagedBy` 特性门控的配置。
 
-{{% alert title="注意" color="primary" %}}
-`JobManagedBy` 特性门控在 Kubernetes v1.30 和 v1.31 版本中默认禁用，在 v1.32 版本中默认启用。
-{{% /alert %}}
-
 ### 集群启用 JobManagedBy {#cluster-with-jobmanagedby-enabled}
 
 当集群启用 `JobManagedBy` 时，建议配置 Kueue 启用 `MultiKueueBatchJobWithManagedBy` 特性门控。
diff --git a/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/swagger.json b/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/swagger.json
index bcc608b9f..162df725c 100644
--- a/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/swagger.json
+++ b/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/swagger.json
@@ -72,6 +72,14 @@
           "type": "string",
           "default": ""
         },
+        "emulationMajor": {
+          "description": "EmulationMajor is the major version of the emulation version",
+          "type": "string"
+        },
+        "emulationMinor": {
+          "description": "EmulationMinor is the minor version of the emulation version",
+          "type": "string"
+        },
         "gitCommit": {
           "type": "string",
           "default": ""
@@ -89,10 +97,20 @@
           "default": ""
         },
         "major": {
+          "description": "Major is the major version of the binary version",
           "type": "string",
           "default": ""
         },
+        "minCompatibilityMajor": {
+          "description": "MinCompatibilityMajor is the major version of the minimum compatibility version",
+          "type": "string"
+        },
+        "minCompatibilityMinor": {
+          "description": "MinCompatibilityMinor is the minor version of the minimum compatibility version",
+          "type": "string"
+        },
         "minor": {
+          "description": "Minor is the minor version of the binary version",
           "type": "string",
           "default": ""
         },
@@ -445,6 +463,10 @@
           "type": "integer",
           "format": "int64"
         },
+        "ignoreStoreReadErrorWithClusterBreakingPotential": {
+          "description": "if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it",
+          "type": "boolean"
+        },
         "kind": {
           "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds",
           "type": "string"
diff --git a/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/zz_generated.deepcopy.go b/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/zz_generated.deepcopy.go
index e85549f50..f4bed7c25 100644
--- a/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/zz_generated.deepcopy.go
+++ b/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/zz_generated.deepcopy.go
@@ -1,7 +1,7 @@
 //go:build !ignore_autogenerated
 // +build !ignore_autogenerated
 
-// Copyright 2024 The Kubeflow Authors.
+// Copyright 2025 The Kubeflow Authors.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/zz_generated.defaults.go b/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/zz_generated.defaults.go
index 1e377e17f..1c7f666c2 100644
--- a/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/zz_generated.defaults.go
+++ b/vendor/github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1/zz_generated.defaults.go
@@ -1,7 +1,7 @@
 //go:build !ignore_autogenerated
 // +build !ignore_autogenerated
 
-// Copyright 2024 The Kubeflow Authors.
+// Copyright 2025 The Kubeflow Authors.
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/core/clustertrainingruntime.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/core/clustertrainingruntime.go
index 2e3c653e7..d4a2ac8ab 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/core/clustertrainingruntime.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/core/clustertrainingruntime.go
@@ -21,6 +21,7 @@ import (
 	"errors"
 	"fmt"
 
+	apiruntime "k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/util/validation/field"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -53,7 +54,7 @@ func NewClusterTrainingRuntime(context.Context, client.Client, client.FieldIndex
 	}, nil
 }
 
-func (r *ClusterTrainingRuntime) NewObjects(ctx context.Context, trainJob *trainer.TrainJob) ([]any, error) {
+func (r *ClusterTrainingRuntime) NewObjects(ctx context.Context, trainJob *trainer.TrainJob) ([]apiruntime.ApplyConfiguration, error) {
 	var clTrainingRuntime trainer.ClusterTrainingRuntime
 	if err := r.client.Get(ctx, client.ObjectKey{Name: trainJob.Spec.RuntimeRef.Name}, &clTrainingRuntime); err != nil {
 		return nil, fmt.Errorf("%w: %w", errorNotFoundSpecifiedClusterTrainingRuntime, err)
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/core/trainingruntime.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/core/trainingruntime.go
index 0f03d467e..0f8d4e8ac 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/core/trainingruntime.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/core/trainingruntime.go
@@ -25,6 +25,7 @@ import (
 
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	apiruntime "k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/util/strategicpatch"
 	"k8s.io/apimachinery/pkg/util/validation/field"
@@ -79,7 +80,7 @@ func NewTrainingRuntime(ctx context.Context, c client.Client, indexer client.Fie
 	return trainingRuntimeFactory, nil
 }
 
-func (r *TrainingRuntime) NewObjects(ctx context.Context, trainJob *trainer.TrainJob) ([]any, error) {
+func (r *TrainingRuntime) NewObjects(ctx context.Context, trainJob *trainer.TrainJob) ([]apiruntime.ApplyConfiguration, error) {
 	var trainingRuntime trainer.TrainingRuntime
 	err := r.client.Get(ctx, client.ObjectKey{Namespace: trainJob.Namespace, Name: trainJob.Spec.RuntimeRef.Name}, &trainingRuntime)
 	if err != nil {
@@ -159,7 +160,6 @@ func (r *TrainingRuntime) newRuntimeInfo(
 		runtime.WithMLPolicySource(mlPolicy),
 		runtime.WithPodGroupPolicy(podGroupPolicy),
 		runtime.WithTemplateSpecObjApply(jobSetSpecApply),
-		runtime.WithPodSetSyncer(syncPodSets),
 	}
 
 	for i, rJob := range jobSetSpecApply.ReplicatedJobs {
@@ -237,34 +237,6 @@ func (r *TrainingRuntime) mergePodTemplateOverrides(trainJob *trainer.TrainJob,
 	return nil
 }
 
-func syncPodSets(info *runtime.Info) {
-	jsSpec, ok := runtime.TemplateSpecApply[jobsetv1alpha2ac.JobSetSpecApplyConfiguration](info)
-	if !ok {
-		return
-	}
-	for psIdx, ps := range info.TemplateSpec.PodSets {
-		if ps.Count != nil {
-			jsSpec.ReplicatedJobs[psIdx].Template.Spec.Parallelism = ps.Count
-			jsSpec.ReplicatedJobs[psIdx].Template.Spec.Completions = ps.Count
-		}
-		apply.UpsertVolumes(&jsSpec.ReplicatedJobs[psIdx].Template.Spec.Template.Spec.Volumes, ps.Volumes...)
-		for containerIdx, container := range ps.Containers {
-			apply.UpsertEnvVars(
-				&jsSpec.ReplicatedJobs[psIdx].Template.Spec.Template.Spec.Containers[containerIdx].Env,
-				container.Env...,
-			)
-			apply.UpsertPort(
-				&jsSpec.ReplicatedJobs[psIdx].Template.Spec.Template.Spec.Containers[containerIdx].Ports,
-				container.Ports...,
-			)
-			apply.UpsertVolumeMounts(
-				&jsSpec.ReplicatedJobs[psIdx].Template.Spec.Template.Spec.Containers[containerIdx].VolumeMounts,
-				container.VolumeMounts...,
-			)
-		}
-	}
-}
-
 func (r *TrainingRuntime) TrainJobStatus(ctx context.Context, trainJob *trainer.TrainJob) (*trainer.TrainJobStatus, error) {
 	return r.framework.RunTrainJobStatusPlugin(ctx, trainJob)
 }
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/core/framework.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/core/framework.go
index dc654d3ae..c878e5450 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/core/framework.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/core/framework.go
@@ -20,6 +20,7 @@ import (
 	"context"
 	"errors"
 
+	apiruntime "k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/validation/field"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
@@ -131,8 +132,8 @@ func (f *Framework) RunPodNetworkPlugins(info *runtime.Info, trainJob *trainer.T
 	return nil
 }
 
-func (f *Framework) RunComponentBuilderPlugins(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]any, error) {
-	var objs []any
+func (f *Framework) RunComponentBuilderPlugins(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]apiruntime.ApplyConfiguration, error) {
+	var objs []apiruntime.ApplyConfiguration
 	for _, plugin := range f.componentBuilderPlugins {
 		components, err := plugin.Build(ctx, info, trainJob)
 		if err != nil {
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/interface.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/interface.go
index 703379c1f..b84dfe347 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/interface.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/interface.go
@@ -19,6 +19,7 @@ package framework
 import (
 	"context"
 
+	apiruntime "k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/validation/field"
 	"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
 
@@ -57,7 +58,7 @@ type PodNetworkPlugin interface {
 
 type ComponentBuilderPlugin interface {
 	Plugin
-	Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]any, error)
+	Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]apiruntime.ApplyConfiguration, error)
 }
 
 type TrainJobStatusPlugin interface {
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/coscheduling/coscheduling.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/coscheduling/coscheduling.go
index abcfd4634..0984b5891 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/coscheduling/coscheduling.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/coscheduling/coscheduling.go
@@ -90,7 +90,7 @@ func (c *CoScheduling) EnforcePodGroupPolicy(info *runtime.Info, trainJob *train
 	return nil
 }
 
-func (c *CoScheduling) Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]any, error) {
+func (c *CoScheduling) Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]apiruntime.ApplyConfiguration, error) {
 	if info == nil || info.RuntimePolicy.PodGroupPolicy == nil || info.RuntimePolicy.PodGroupPolicy.Coscheduling == nil || trainJob == nil {
 		return nil, nil
 	}
@@ -135,7 +135,7 @@ func (c *CoScheduling) Build(ctx context.Context, info *runtime.Info, trainJob *
 		WithController(true).
 		WithBlockOwnerDeletion(true))
 
-	return []any{podGroup}, nil
+	return []apiruntime.ApplyConfiguration{podGroup}, nil
 }
 
 type PodGroupRuntimeClassHandler struct {
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/jobset/jobset.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/jobset/jobset.go
index 982e8d0af..13da9eb62 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/jobset/jobset.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/jobset/jobset.go
@@ -42,6 +42,7 @@ import (
 	jobsetv1alpha2ac "sigs.k8s.io/jobset/client-go/applyconfiguration/jobset/v1alpha2"
 
 	trainer "github.com/kubeflow/trainer/v2/pkg/apis/trainer/v1alpha1"
+	"github.com/kubeflow/trainer/v2/pkg/apply"
 	"github.com/kubeflow/trainer/v2/pkg/constants"
 	"github.com/kubeflow/trainer/v2/pkg/runtime"
 	"github.com/kubeflow/trainer/v2/pkg/runtime/framework"
@@ -230,18 +231,13 @@ func (j *JobSet) IdentifyPodNetwork(info *runtime.Info, trainJob *trainer.TrainJ
 			}
 		}
 	}
-	info.SyncPodSetsToTemplateSpec()
 	return nil
 }
 
-func (j *JobSet) Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]any, error) {
+func (j *JobSet) Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]apiruntime.ApplyConfiguration, error) {
 	if info == nil || trainJob == nil {
 		return nil, fmt.Errorf("runtime info or object is missing")
 	}
-	jobSetSpec, ok := runtime.TemplateSpecApply[jobsetv1alpha2ac.JobSetSpecApplyConfiguration](info)
-	if !ok {
-		return nil, nil
-	}
 
 	// Do not update the JobSet if it already exists and is not suspended
 	oldJobSet := &jobsetv1alpha2.JobSet{}
@@ -257,6 +253,33 @@ func (j *JobSet) Build(ctx context.Context, info *runtime.Info, trainJob *traine
 		return nil, nil
 	}
 
+	jobSetSpec, ok := runtime.TemplateSpecApply[jobsetv1alpha2ac.JobSetSpecApplyConfiguration](info)
+	if !ok {
+		return nil, nil
+	}
+
+	for psIdx, ps := range info.TemplateSpec.PodSets {
+		if ps.Count != nil {
+			jobSetSpec.ReplicatedJobs[psIdx].Template.Spec.Parallelism = ps.Count
+			jobSetSpec.ReplicatedJobs[psIdx].Template.Spec.Completions = ps.Count
+		}
+		apply.UpsertVolumes(&jobSetSpec.ReplicatedJobs[psIdx].Template.Spec.Template.Spec.Volumes, ps.Volumes...)
+		for containerIdx, container := range ps.Containers {
+			apply.UpsertEnvVars(
+				&jobSetSpec.ReplicatedJobs[psIdx].Template.Spec.Template.Spec.Containers[containerIdx].Env,
+				container.Env...,
+			)
+			apply.UpsertPort(
+				&jobSetSpec.ReplicatedJobs[psIdx].Template.Spec.Template.Spec.Containers[containerIdx].Ports,
+				container.Ports...,
+			)
+			apply.UpsertVolumeMounts(
+				&jobSetSpec.ReplicatedJobs[psIdx].Template.Spec.Template.Spec.Containers[containerIdx].VolumeMounts,
+				container.VolumeMounts...,
+			)
+		}
+	}
+
 	// Init the JobSet apply configuration from the runtime template spec
 	jobSetBuilder := NewBuilder(jobsetv1alpha2ac.JobSet(trainJob.Name, trainJob.Namespace).
 		WithLabels(maps.Clone(info.Labels)).
@@ -280,7 +303,7 @@ func (j *JobSet) Build(ctx context.Context, info *runtime.Info, trainJob *traine
 			WithController(true).
 			WithBlockOwnerDeletion(true))
 
-	return []any{jobSet}, nil
+	return []apiruntime.ApplyConfiguration{jobSet}, nil
 }
 
 func (j *JobSet) Status(ctx context.Context, trainJob *trainer.TrainJob) (*trainer.TrainJobStatus, error) {
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/mpi/mpi.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/mpi/mpi.go
index 053fd38e9..17136bc70 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/mpi/mpi.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/mpi/mpi.go
@@ -220,7 +220,7 @@ func (m *MPI) EnforceMLPolicy(info *runtime.Info, trainJob *trainer.TrainJob) er
 			}
 		}
 	}
-	info.SyncPodSetsToTemplateSpec()
+
 	return nil
 }
 
@@ -245,12 +245,12 @@ func (m *MPI) ReconcilerBuilders() []runtime.ReconcilerBuilder {
 	}
 }
 
-func (m *MPI) Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]any, error) {
+func (m *MPI) Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]apiruntime.ApplyConfiguration, error) {
 	if info == nil || info.RuntimePolicy.MLPolicySource == nil || info.RuntimePolicy.MLPolicySource.MPI == nil {
 		return nil, nil
 	}
 
-	var objects []any
+	var objects []apiruntime.ApplyConfiguration
 
 	// SSHAuthSecret is immutable.
 	if err := m.client.Get(ctx, client.ObjectKey{Name: sshAuthSecretName(trainJob.Name), Namespace: trainJob.Namespace}, &corev1.Secret{}); err != nil {
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/plainml/plainml.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/plainml/plainml.go
index 517bee5c7..25efe5501 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/plainml/plainml.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/plainml/plainml.go
@@ -62,6 +62,6 @@ func (p *PlainML) EnforceMLPolicy(info *runtime.Info, trainJob *trainer.TrainJob
 			apply.UpsertEnvVars(&trainerContainer.Env, apply.EnvVars(trainJob.Spec.Trainer.Env...)...)
 		}
 	}
-	info.SyncPodSetsToTemplateSpec()
+
 	return nil
 }
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/torch/torch.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/torch/torch.go
index 0aef2c759..733fbc795 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/torch/torch.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/torch/torch.go
@@ -184,7 +184,7 @@ func (t *Torch) EnforceMLPolicy(info *runtime.Info, trainJob *trainer.TrainJob)
 		// Add container port for the headless service.
 		apply.UpsertPort(&trainerContainer.Ports, *corev1ac.ContainerPort().WithContainerPort(constants.ContainerTrainerPort))
 	}
-	info.SyncPodSetsToTemplateSpec()
+
 	return nil
 }
 
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/volcano/volcano.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/volcano/volcano.go
index 376e6515a..6f32d7e05 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/volcano/volcano.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/framework/plugins/volcano/volcano.go
@@ -138,7 +138,7 @@ func (v *Volcano) EnforcePodGroupPolicy(info *runtime.Info, trainJob *trainer.Tr
 	return nil
 }
 
-func (v *Volcano) Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]any, error) {
+func (v *Volcano) Build(ctx context.Context, info *runtime.Info, trainJob *trainer.TrainJob) ([]apiruntime.ApplyConfiguration, error) {
 	if info == nil || info.RuntimePolicy.PodGroupPolicy == nil || info.RuntimePolicy.PodGroupPolicy.Volcano == nil || trainJob == nil {
 		return nil, nil
 	}
@@ -208,7 +208,7 @@ func (v *Volcano) Build(ctx context.Context, info *runtime.Info, trainJob *train
 		WithController(true).
 		WithBlockOwnerDeletion(true))
 
-	return []any{pg}, nil
+	return []apiruntime.ApplyConfiguration{pg}, nil
 }
 
 type PodGroupRuntimeClassHandler struct {
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/interface.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/interface.go
index 3e831b8fa..a4f17a1a5 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/interface.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/interface.go
@@ -19,6 +19,7 @@ package runtime
 import (
 	"context"
 
+	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/validation/field"
 	"sigs.k8s.io/controller-runtime/pkg/builder"
 	"sigs.k8s.io/controller-runtime/pkg/cache"
@@ -31,11 +32,7 @@ import (
 type ReconcilerBuilder func(*builder.Builder, client.Client, cache.Cache) *builder.Builder
 
 type Runtime interface {
-
-	// TODO (astefanutti): Change the return type from []any to []runtime.ApplyConfiguration when
-	// https://github.com/kubernetes/kubernetes/pull/129313 becomes available
-
-	NewObjects(ctx context.Context, trainJob *trainer.TrainJob) ([]any, error)
+	NewObjects(ctx context.Context, trainJob *trainer.TrainJob) ([]runtime.ApplyConfiguration, error)
 	RuntimeInfo(trainJob *trainer.TrainJob, runtimeTemplateSpec any, mlPolicy *trainer.MLPolicy, podGroupPolicy *trainer.PodGroupPolicy) (*Info, error)
 	TrainJobStatus(ctx context.Context, trainJob *trainer.TrainJob) (*trainer.TrainJobStatus, error)
 	EventHandlerRegistrars() []ReconcilerBuilder
diff --git a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/runtime.go b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/runtime.go
index ec7ed3bdd..b92180d8e 100644
--- a/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/runtime.go
+++ b/vendor/github.com/kubeflow/trainer/v2/pkg/runtime/runtime.go
@@ -33,11 +33,6 @@ import (
 	"github.com/kubeflow/trainer/v2/pkg/constants"
 )
 
-var (
-	defaultPodSetsSyncer = func(*Info) {}
-	syncPodSets          = defaultPodSetsSyncer
-)
-
 type Info struct {
 	// Labels and Annotations to add to the RuntimeJobTemplate.
 	Labels      map[string]string
@@ -172,12 +167,6 @@ func toPodSetContainer(containerApply ...corev1ac.ContainerApplyConfiguration) i
 	}
 }
 
-func WithPodSetSyncer(syncer func(*Info)) InfoOption {
-	return func(o *InfoOptions) {
-		syncPodSets = syncer
-	}
-}
-
 func NewInfo(opts ...InfoOption) *Info {
 	options := defaultOptions
 	for _, opt := range opts {
@@ -202,10 +191,6 @@ func NewInfo(opts ...InfoOption) *Info {
 	return info
 }
 
-func (i *Info) SyncPodSetsToTemplateSpec() {
-	syncPodSets(i)
-}
-
 func TemplateSpecApply[A any](info *Info) (*A, bool) {
 	spec, ok := info.TemplateSpec.ObjApply.(*A)
 	return spec, ok
diff --git a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
index f3ed259c1..092179411 100644
--- a/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
+++ b/vendor/github.com/onsi/ginkgo/v2/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 2.27.2
+
+### Fixes
+- inline automaxprocs to simplify dependencies; this will be removed when Go 1.26 comes out [a69113a]
+
+### Maintenance
+- Fix syntax errors and typo [a99c6e0]
+- Fix paragraph position error [f993df5]
+
 ## 2.27.1
 
 ### Fixes
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/maxprocs.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs.go
similarity index 55%
rename from vendor/github.com/onsi/ginkgo/v2/ginkgo/maxprocs.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs.go
index a7d2b37d6..ee6ac7b5f 100644
--- a/vendor/github.com/onsi/ginkgo/v2/ginkgo/maxprocs.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs.go
@@ -4,5 +4,5 @@
 package main
 
 import (
-	_ "go.uber.org/automaxprocs"
+	_ "github.com/onsi/ginkgo/v2/ginkgo/automaxprocs"
 )
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/README.md b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/README.md
new file mode 100644
index 000000000..e249ebe8b
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/README.md
@@ -0,0 +1,3 @@
+This entire directory is a lightly modified clone of https://github.com/uber-go/automaxprocs
+
+It will be removed when Go 1.26 ships and we no longer need to support Go 1.24 (which does not correctly autodetect maxprocs in containers).
diff --git a/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/automaxprocs.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/automaxprocs.go
new file mode 100644
index 000000000..8a762b51d
--- /dev/null
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/automaxprocs.go
@@ -0,0 +1,71 @@
+// Copyright (c) 2017 Uber Technologies, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+// Package maxprocs lets Go programs easily configure runtime.GOMAXPROCS to
+// match the configured Linux CPU quota. Unlike the top-level automaxprocs
+// package, it lets the caller configure logging and handle errors.
+package automaxprocs
+
+import (
+	"os"
+	"runtime"
+)
+
+func init() {
+	Set()
+}
+
+const _maxProcsKey = "GOMAXPROCS"
+
+type config struct {
+	procs          func(int, func(v float64) int) (int, CPUQuotaStatus, error)
+	minGOMAXPROCS  int
+	roundQuotaFunc func(v float64) int
+}
+
+// Set GOMAXPROCS to match the Linux container CPU quota (if any), returning
+// any error encountered and an undo function.
+//
+// Set is a no-op on non-Linux systems and in Linux environments without a
+// configured CPU quota.
+func Set() error {
+	cfg := &config{
+		procs:          CPUQuotaToGOMAXPROCS,
+		roundQuotaFunc: DefaultRoundFunc,
+		minGOMAXPROCS:  1,
+	}
+
+	// Honor the GOMAXPROCS environment variable if present. Otherwise, amend
+	// `runtime.GOMAXPROCS()` with the current process' CPU quota if the OS is
+	// Linux, and guarantee a minimum value of 1. The minimum guaranteed value
+	// can be overridden using `maxprocs.Min()`.
+	if _, exists := os.LookupEnv(_maxProcsKey); exists {
+		return nil
+	}
+	maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS, cfg.roundQuotaFunc)
+	if err != nil {
+		return err
+	}
+	if status == CPUQuotaUndefined {
+		return nil
+	}
+	runtime.GOMAXPROCS(maxProcs)
+	return nil
+}
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroup.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroup.go
similarity index 99%
rename from vendor/go.uber.org/automaxprocs/internal/cgroups/cgroup.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroup.go
index fe4ecf561..a4676933e 100644
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroup.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroup.go
@@ -21,7 +21,7 @@
 //go:build linux
 // +build linux
 
-package cgroups
+package automaxprocs
 
 import (
 	"bufio"
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups.go
similarity index 99%
rename from vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups.go
index e89f54360..ed384891e 100644
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups.go
@@ -21,7 +21,7 @@
 //go:build linux
 // +build linux
 
-package cgroups
+package automaxprocs
 
 const (
 	// _cgroupFSType is the Linux CGroup file system type used in
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups2.go
similarity index 99%
rename from vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups2.go
index 78556062f..69a0be6b7 100644
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/cgroups2.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cgroups2.go
@@ -21,7 +21,7 @@
 //go:build linux
 // +build linux
 
-package cgroups
+package automaxprocs
 
 import (
 	"bufio"
diff --git a/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_linux.go
similarity index 91%
rename from vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_linux.go
index f9057fd27..2d83343bd 100644
--- a/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_linux.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_linux.go
@@ -21,12 +21,10 @@
 //go:build linux
 // +build linux
 
-package runtime
+package automaxprocs
 
 import (
 	"errors"
-
-	cg "go.uber.org/automaxprocs/internal/cgroups"
 )
 
 // CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
@@ -58,8 +56,8 @@ type queryer interface {
 }
 
 var (
-	_newCgroups2 = cg.NewCGroups2ForCurrentProcess
-	_newCgroups  = cg.NewCGroupsForCurrentProcess
+	_newCgroups2 = NewCGroups2ForCurrentProcess
+	_newCgroups  = NewCGroupsForCurrentProcess
 	_newQueryer  = newQueryer
 )
 
@@ -68,7 +66,7 @@ func newQueryer() (queryer, error) {
 	if err == nil {
 		return cgroups, nil
 	}
-	if errors.Is(err, cg.ErrNotV2) {
+	if errors.Is(err, ErrNotV2) {
 		return _newCgroups()
 	}
 	return nil, err
diff --git a/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_unsupported.go
similarity index 98%
rename from vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_unsupported.go
index e74701508..d2d61e894 100644
--- a/vendor/go.uber.org/automaxprocs/internal/runtime/cpu_quota_unsupported.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/cpu_quota_unsupported.go
@@ -21,7 +21,7 @@
 //go:build !linux
 // +build !linux
 
-package runtime
+package automaxprocs
 
 // CPUQuotaToGOMAXPROCS converts the CPU quota applied to the calling process
 // to a valid GOMAXPROCS value. This is Linux-specific and not supported in the
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/errors.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/errors.go
similarity index 98%
rename from vendor/go.uber.org/automaxprocs/internal/cgroups/errors.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/errors.go
index 94ac75a46..2e235d7d6 100644
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/errors.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/errors.go
@@ -21,7 +21,7 @@
 //go:build linux
 // +build linux
 
-package cgroups
+package automaxprocs
 
 import "fmt"
 
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/mountpoint.go
similarity index 99%
rename from vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/mountpoint.go
index f3877f78a..7c3fa306e 100644
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/mountpoint.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/mountpoint.go
@@ -21,7 +21,7 @@
 //go:build linux
 // +build linux
 
-package cgroups
+package automaxprocs
 
 import (
 	"bufio"
diff --git a/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/runtime.go
similarity index 98%
rename from vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/runtime.go
index f8a2834ac..b8ec7e502 100644
--- a/vendor/go.uber.org/automaxprocs/internal/runtime/runtime.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/runtime.go
@@ -18,7 +18,7 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
-package runtime
+package automaxprocs
 
 import "math"
 
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/subsys.go b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/subsys.go
similarity index 99%
rename from vendor/go.uber.org/automaxprocs/internal/cgroups/subsys.go
rename to vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/subsys.go
index cddc3eaec..881ebd590 100644
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/subsys.go
+++ b/vendor/github.com/onsi/ginkgo/v2/ginkgo/automaxprocs/subsys.go
@@ -21,7 +21,7 @@
 //go:build linux
 // +build linux
 
-package cgroups
+package automaxprocs
 
 import (
 	"bufio"
diff --git a/vendor/github.com/onsi/ginkgo/v2/types/version.go b/vendor/github.com/onsi/ginkgo/v2/types/version.go
index 855e7cbd9..b9c1ea985 100644
--- a/vendor/github.com/onsi/ginkgo/v2/types/version.go
+++ b/vendor/github.com/onsi/ginkgo/v2/types/version.go
@@ -1,3 +1,3 @@
 package types
 
-const VERSION = "2.27.1"
+const VERSION = "2.27.2"
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/raycluster_types.go b/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/raycluster_types.go
index 285b88618..6a6d40b82 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/raycluster_types.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/raycluster_types.go
@@ -75,6 +75,16 @@ type HeadGroupSpec struct {
 	// EnableIngress indicates whether operator should create ingress object for head service or not.
 	// +optional
 	EnableIngress *bool `json:"enableIngress,omitempty"`
+	// Resources specifies the resource quantities for the head group.
+	// These values override the resources passed to `rayStartParams` for the group, but
+	// have no effect on the resources set at the K8s Pod container level.
+	// +optional
+	Resources map[string]string `json:"resources,omitempty"`
+	// Labels specifies the Ray node labels for the head group.
+	// These labels will also be added to the Pods of this head group and override the `--labels`
+	// argument passed to `rayStartParams`.
+	// +optional
+	Labels map[string]string `json:"labels,omitempty"`
 	// RayStartParams are the params of the start command: node-manager-port, object-store-memory, ...
 	// +optional
 	RayStartParams map[string]string `json:"rayStartParams"`
@@ -87,7 +97,7 @@ type HeadGroupSpec struct {
 type WorkerGroupSpec struct {
 	// Suspend indicates whether a worker group should be suspended.
 	// A suspended worker group will have all pods deleted.
-	// This is not a user-facing API and is only used by RayJob DeletionPolicy.
+	// This is not a user-facing API and is only used by RayJob DeletionStrategy.
 	// +optional
 	Suspend *bool `json:"suspend,omitempty"`
 	// we can have multiple worker groups, we distinguish them by name
@@ -106,6 +116,16 @@ type WorkerGroupSpec struct {
 	// This value is only used with the Ray Autoscaler enabled and defaults to the value set by the AutoscalingConfig if not specified for this worker group.
 	// +optional
 	IdleTimeoutSeconds *int32 `json:"idleTimeoutSeconds,omitempty"`
+	// Resources specifies the resource quantities for this worker group.
+	// These values override the resources passed to `rayStartParams` for the group, but
+	// have no effect on the resources set at the K8s Pod container level.
+	// +optional
+	Resources map[string]string `json:"resources,omitempty"`
+	// Labels specifies the Ray node labels for this worker group.
+	// These labels will also be added to the Pods of this worker group and override the `--labels`
+	// argument passed to `rayStartParams`.
+	// +optional
+	Labels map[string]string `json:"labels,omitempty"`
 	// RayStartParams are the params of the start command: address, object-store-memory, ...
 	// +optional
 	RayStartParams map[string]string `json:"rayStartParams"`
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/rayjob_types.go b/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/rayjob_types.go
index 1f9f58d23..705d50dfd 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/rayjob_types.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/rayjob_types.go
@@ -45,15 +45,16 @@ func IsJobTerminal(status JobStatus) bool {
 type JobDeploymentStatus string
 
 const (
-	JobDeploymentStatusNew          JobDeploymentStatus = ""
-	JobDeploymentStatusInitializing JobDeploymentStatus = "Initializing"
-	JobDeploymentStatusRunning      JobDeploymentStatus = "Running"
-	JobDeploymentStatusComplete     JobDeploymentStatus = "Complete"
-	JobDeploymentStatusFailed       JobDeploymentStatus = "Failed"
-	JobDeploymentStatusSuspending   JobDeploymentStatus = "Suspending"
-	JobDeploymentStatusSuspended    JobDeploymentStatus = "Suspended"
-	JobDeploymentStatusRetrying     JobDeploymentStatus = "Retrying"
-	JobDeploymentStatusWaiting      JobDeploymentStatus = "Waiting"
+	JobDeploymentStatusNew              JobDeploymentStatus = ""
+	JobDeploymentStatusInitializing     JobDeploymentStatus = "Initializing"
+	JobDeploymentStatusRunning          JobDeploymentStatus = "Running"
+	JobDeploymentStatusComplete         JobDeploymentStatus = "Complete"
+	JobDeploymentStatusFailed           JobDeploymentStatus = "Failed"
+	JobDeploymentStatusValidationFailed JobDeploymentStatus = "ValidationFailed"
+	JobDeploymentStatusSuspending       JobDeploymentStatus = "Suspending"
+	JobDeploymentStatusSuspended        JobDeploymentStatus = "Suspended"
+	JobDeploymentStatusRetrying         JobDeploymentStatus = "Retrying"
+	JobDeploymentStatusWaiting          JobDeploymentStatus = "Waiting"
 )
 
 // IsJobDeploymentTerminal returns true if the given JobDeploymentStatus
@@ -74,6 +75,7 @@ const (
 	DeadlineExceeded                                 JobFailedReason = "DeadlineExceeded"
 	AppFailed                                        JobFailedReason = "AppFailed"
 	JobDeploymentStatusTransitionGracePeriodExceeded JobFailedReason = "JobDeploymentStatusTransitionGracePeriodExceeded"
+	ValidationFailed                                 JobFailedReason = "ValidationFailed"
 )
 
 type JobSubmissionMode string
@@ -82,15 +84,95 @@ const (
 	K8sJobMode      JobSubmissionMode = "K8sJobMode"      // Submit job via Kubernetes Job
 	HTTPMode        JobSubmissionMode = "HTTPMode"        // Submit job via HTTP request
 	InteractiveMode JobSubmissionMode = "InteractiveMode" // Don't submit job in KubeRay. Instead, wait for user to submit job and provide the job submission ID.
+	SidecarMode     JobSubmissionMode = "SidecarMode"     // Submit job via a sidecar container in the Ray head Pod
 )
 
-type DeletionPolicy string
+// DeletionStrategy configures automated cleanup after the RayJob reaches a terminal state.
+// Two mutually exclusive styles are supported:
+//
+//	Legacy: provide both onSuccess and onFailure (deprecated; removal planned for 1.6.0). May be combined with shutdownAfterJobFinishes and (optionally) global TTLSecondsAfterFinished.
+//	Rules: provide deletionRules (non-empty list). Rules mode is incompatible with shutdownAfterJobFinishes, legacy fields, and the global TTLSecondsAfterFinished (use per‑rule condition.ttlSeconds instead).
+//
+// Semantics:
+//   - A non-empty deletionRules selects rules mode; empty lists are treated as unset.
+//   - Legacy requires both onSuccess and onFailure; specifying only one is invalid.
+//   - Global TTLSecondsAfterFinished > 0 requires shutdownAfterJobFinishes=true; therefore it cannot be used with rules mode or with legacy alone (no shutdown).
+//   - Feature gate RayJobDeletionPolicy must be enabled when this block is present.
+//
+// Validation:
+//   - CRD XValidations prevent mixing legacy fields with deletionRules and enforce legacy completeness.
+//   - Controller logic enforces rules vs shutdown exclusivity and TTL constraints.
+//   - onSuccess/onFailure are deprecated; migration to deletionRules is encouraged.
+//
+// +kubebuilder:validation:XValidation:rule="!((has(self.onSuccess) || has(self.onFailure)) && has(self.deletionRules))",message="legacy policies (onSuccess/onFailure) and deletionRules cannot be used together within the same deletionStrategy"
+// +kubebuilder:validation:XValidation:rule="((has(self.onSuccess) && has(self.onFailure)) || has(self.deletionRules))",message="deletionStrategy requires either BOTH onSuccess and onFailure, OR the deletionRules field (cannot be empty)"
+type DeletionStrategy struct {
+	// OnSuccess is the deletion policy for a successful RayJob.
+	// Deprecated: Use `deletionRules` instead for more flexible, multi-stage deletion strategies.
+	// This field will be removed in release 1.6.0.
+	// +optional
+	OnSuccess *DeletionPolicy `json:"onSuccess,omitempty"`
+
+	// OnFailure is the deletion policy for a failed RayJob.
+	// Deprecated: Use `deletionRules` instead for more flexible, multi-stage deletion strategies.
+	// This field will be removed in release 1.6.0.
+	// +optional
+	OnFailure *DeletionPolicy `json:"onFailure,omitempty"`
+
+	// DeletionRules is a list of deletion rules, processed based on their trigger conditions.
+	// While the rules can be used to define a sequence, if multiple rules are overdue (e.g., due to controller downtime),
+	// the most impactful rule (e.g., DeleteSelf) will be executed first to prioritize resource cleanup.
+	// +optional
+	// +listType=atomic
+	// +kubebuilder:validation:MinItems=1
+	DeletionRules []DeletionRule `json:"deletionRules,omitempty"`
+}
+
+// DeletionRule defines a single deletion action and its trigger condition.
+// This is the new, recommended way to define deletion behavior.
+type DeletionRule struct {
+	// Policy is the action to take when the condition is met. This field is required.
+	// +kubebuilder:validation:Enum=DeleteCluster;DeleteWorkers;DeleteSelf;DeleteNone
+	Policy DeletionPolicyType `json:"policy"`
+
+	// The condition under which this deletion rule is triggered. This field is required.
+	Condition DeletionCondition `json:"condition"`
+}
+
+// DeletionCondition specifies the trigger conditions for a deletion action.
+type DeletionCondition struct {
+	// JobStatus is the terminal status of the RayJob that triggers this condition. This field is required.
+	// For the initial implementation, only "SUCCEEDED" and "FAILED" are supported.
+	// +kubebuilder:validation:Enum=SUCCEEDED;FAILED
+	JobStatus JobStatus `json:"jobStatus"`
+
+	// TTLSeconds is the time in seconds from when the JobStatus
+	// reaches the specified terminal state to when this deletion action should be triggered.
+	// The value must be a non-negative integer.
+	// +kubebuilder:default=0
+	// +kubebuilder:validation:Minimum=0
+	// +optional
+	TTLSeconds int32 `json:"ttlSeconds,omitempty"`
+}
+
+// DeletionPolicy is the legacy single-stage deletion policy.
+// Deprecated: This struct is part of the legacy API. Use DeletionRule for new configurations.
+type DeletionPolicy struct {
+	// Policy is the action to take when the condition is met.
+	// This field is logically required when using the legacy OnSuccess/OnFailure policies.
+	// It is marked as '+optional' at the API level to allow the 'deletionRules' field to be used instead.
+	// +kubebuilder:validation:Enum=DeleteCluster;DeleteWorkers;DeleteSelf;DeleteNone
+	// +optional
+	Policy *DeletionPolicyType `json:"policy,omitempty"`
+}
+
+type DeletionPolicyType string
 
 const (
-	DeleteClusterDeletionPolicy DeletionPolicy = "DeleteCluster" // Deletion policy to delete the entire RayCluster custom resource on job completion.
-	DeleteWorkersDeletionPolicy DeletionPolicy = "DeleteWorkers" // Deletion policy to delete only the workers on job completion.
-	DeleteSelfDeletionPolicy    DeletionPolicy = "DeleteSelf"    // Deletion policy to delete the RayJob custom resource (and all associated resources) on job completion.
-	DeleteNoneDeletionPolicy    DeletionPolicy = "DeleteNone"    // Deletion policy to delete no resources on job completion.
+	DeleteCluster DeletionPolicyType = "DeleteCluster" // To delete the entire RayCluster custom resource on job completion.
+	DeleteWorkers DeletionPolicyType = "DeleteWorkers" // To delete only the workers on job completion.
+	DeleteSelf    DeletionPolicyType = "DeleteSelf"    // To delete the RayJob custom resource (and all associated resources) on job completion.
+	DeleteNone    DeletionPolicyType = "DeleteNone"    // To delete no resources on job completion.
 )
 
 type SubmitterConfig struct {
@@ -144,13 +226,14 @@ type RayJobSpec struct {
 	// +kubebuilder:validation:XValidation:rule="self in ['ray.io/kuberay-operator', 'kueue.x-k8s.io/multikueue']",message="the managedBy field value must be either 'ray.io/kuberay-operator' or 'kueue.x-k8s.io/multikueue'"
 	// +optional
 	ManagedBy *string `json:"managedBy,omitempty"`
-	// DeletionPolicy indicates what resources of the RayJob are deleted upon job completion.
-	// Valid values are 'DeleteCluster', 'DeleteWorkers', 'DeleteSelf' or 'DeleteNone'.
-	// If unset, deletion policy is based on 'spec.shutdownAfterJobFinishes'.
-	// This field requires the RayJobDeletionPolicy feature gate to be enabled.
-	// +kubebuilder:validation:XValidation:rule="self in ['DeleteCluster', 'DeleteWorkers', 'DeleteSelf', 'DeleteNone']",message="the deletionPolicy field value must be either 'DeleteCluster', 'DeleteWorkers', 'DeleteSelf', or 'DeleteNone'"
-	// +optional
-	DeletionPolicy *DeletionPolicy `json:"deletionPolicy,omitempty"`
+	// DeletionStrategy automates post-completion cleanup.
+	// Choose one style or omit:
+	//   - Legacy: both onSuccess & onFailure (deprecated; may combine with shutdownAfterJobFinishes and TTLSecondsAfterFinished).
+	//   - Rules: deletionRules (non-empty) — incompatible with shutdownAfterJobFinishes, legacy fields, and global TTLSecondsAfterFinished (use per-rule condition.ttlSeconds).
+	// Global TTLSecondsAfterFinished > 0 requires shutdownAfterJobFinishes=true.
+	// Feature gate RayJobDeletionPolicy must be enabled when this field is set.
+	// +optional
+	DeletionStrategy *DeletionStrategy `json:"deletionStrategy,omitempty"`
 	// Entrypoint represents the command to start execution.
 	// +optional
 	Entrypoint string `json:"entrypoint,omitempty"`
@@ -165,6 +248,7 @@ type RayJobSpec struct {
 	// In "K8sJobMode", the KubeRay operator creates a submitter Kubernetes Job to submit the Ray job.
 	// In "HTTPMode", the KubeRay operator sends a request to the RayCluster to create a Ray job.
 	// In "InteractiveMode", the KubeRay operator waits for a user to submit a job to the Ray cluster.
+	// In "SidecarMode", the KubeRay operator injects a container into the Ray head Pod that acts as the job submitter to submit the Ray job.
 	// +kubebuilder:default:=K8sJobMode
 	// +optional
 	SubmissionMode JobSubmissionMode `json:"submissionMode,omitempty"`
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/rayservice_types.go b/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/rayservice_types.go
index 3b528faae..83b9775f3 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/rayservice_types.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/rayservice_types.go
@@ -22,6 +22,9 @@ const (
 type RayServiceUpgradeType string
 
 const (
+	// During upgrade, NewClusterWithIncrementalUpgrade strategy will create an upgraded cluster to gradually scale
+	// and migrate traffic to using Gateway API.
+	NewClusterWithIncrementalUpgrade RayServiceUpgradeType = "NewClusterWithIncrementalUpgrade"
 	// During upgrade, NewCluster strategy will create new upgraded cluster and switch to it when it becomes ready
 	NewCluster RayServiceUpgradeType = "NewCluster"
 	// No new cluster will be created while the strategy is set to None
@@ -57,14 +60,36 @@ var DeploymentStatusEnum = struct {
 	UNHEALTHY: "UNHEALTHY",
 }
 
+// These options are currently only supported for the IncrementalUpgrade type.
+type ClusterUpgradeOptions struct {
+	// The capacity of serve requests the upgraded cluster should scale to handle each interval.
+	// Defaults to 100%.
+	// +kubebuilder:default:=100
+	MaxSurgePercent *int32 `json:"maxSurgePercent,omitempty"`
+	// The percentage of traffic to switch to the upgraded RayCluster at a set interval after scaling by MaxSurgePercent.
+	StepSizePercent *int32 `json:"stepSizePercent"`
+	// The interval in seconds between transferring StepSize traffic from the old to new RayCluster.
+	IntervalSeconds *int32 `json:"intervalSeconds"`
+	// The name of the Gateway Class installed by the Kubernetes Cluster admin.
+	GatewayClassName string `json:"gatewayClassName"`
+}
+
 type RayServiceUpgradeStrategy struct {
 	// Type represents the strategy used when upgrading the RayService. Currently supports `NewCluster` and `None`.
 	// +optional
 	Type *RayServiceUpgradeType `json:"type,omitempty"`
+	// ClusterUpgradeOptions defines the behavior of a NewClusterWithIncrementalUpgrade type.
+	// RayServiceIncrementalUpgrade feature gate must be enabled to set ClusterUpgradeOptions.
+	ClusterUpgradeOptions *ClusterUpgradeOptions `json:"clusterUpgradeOptions,omitempty"`
 }
 
 // RayServiceSpec defines the desired state of RayService
 type RayServiceSpec struct {
+	// RayClusterDeletionDelaySeconds specifies the delay, in seconds, before deleting old RayClusters.
+	// The default value is 60 seconds.
+	// +kubebuilder:validation:Minimum=0
+	// +optional
+	RayClusterDeletionDelaySeconds *int32 `json:"rayClusterDeletionDelaySeconds,omitempty"`
 	// Deprecated: This field is not used anymore. ref: https://github.com/ray-project/kuberay/issues/1685
 	// +optional
 	ServiceUnhealthySecondThreshold *int32 `json:"serviceUnhealthySecondThreshold,omitempty"`
@@ -124,6 +149,20 @@ type RayServiceStatus struct {
 	// Important: Run "make" to regenerate code after modifying this file
 	// +optional
 	Applications map[string]AppStatus `json:"applicationStatuses,omitempty"`
+	// TargetCapacity is the `target_capacity` percentage for all Serve replicas
+	// across the cluster for this RayService. The `num_replicas`, `min_replicas`, `max_replicas`,
+	// and `initial_replicas` for each deployment will be scaled by this percentage."
+	// +optional
+	TargetCapacity *int32 `json:"targetCapacity,omitempty"`
+	// TrafficRoutedPercent is the percentage of traffic that is routed to the Serve service
+	// for this RayService. TrafficRoutedPercent is updated to reflect the weight on the HTTPRoute
+	// created for this RayService during incremental upgrades to a new cluster.
+	// +optional
+	TrafficRoutedPercent *int32 `json:"trafficRoutedPercent,omitempty"`
+	// LastTrafficMigratedTime is the last time that TrafficRoutedPercent was updated to a new value
+	// for this RayService.
+	// +optional
+	LastTrafficMigratedTime *metav1.Time `json:"lastTrafficMigratedTime,omitempty"`
 	// +optional
 	RayClusterName string `json:"rayClusterName,omitempty"`
 	// +optional
@@ -161,6 +200,7 @@ const (
 
 const (
 	RayServiceInitializing         RayServiceConditionReason = "Initializing"
+	RayServiceInitializingTimeout  RayServiceConditionReason = "InitializingTimeout"
 	ZeroServeEndpoints             RayServiceConditionReason = "ZeroServeEndpoints"
 	NonZeroServeEndpoints          RayServiceConditionReason = "NonZeroServeEndpoints"
 	BothActivePendingClustersExist RayServiceConditionReason = "BothActivePendingClustersExist"
@@ -179,8 +219,7 @@ const (
 type RayService struct {
 	metav1.TypeMeta   `json:",inline"`
 	metav1.ObjectMeta `json:"metadata,omitempty"`
-
-	Spec RayServiceSpec `json:"spec,omitempty"`
+	Spec              RayServiceSpec `json:"spec,omitempty"`
 	// +optional
 	Status RayServiceStatuses `json:"status,omitempty"`
 }
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/zz_generated.deepcopy.go b/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/zz_generated.deepcopy.go
index 03cf7d778..8deb75000 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/zz_generated.deepcopy.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/apis/ray/v1/zz_generated.deepcopy.go
@@ -103,6 +103,117 @@ func (in *AutoscalerOptions) DeepCopy() *AutoscalerOptions {
 	return out
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *ClusterUpgradeOptions) DeepCopyInto(out *ClusterUpgradeOptions) {
+	*out = *in
+	if in.MaxSurgePercent != nil {
+		in, out := &in.MaxSurgePercent, &out.MaxSurgePercent
+		*out = new(int32)
+		**out = **in
+	}
+	if in.StepSizePercent != nil {
+		in, out := &in.StepSizePercent, &out.StepSizePercent
+		*out = new(int32)
+		**out = **in
+	}
+	if in.IntervalSeconds != nil {
+		in, out := &in.IntervalSeconds, &out.IntervalSeconds
+		*out = new(int32)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterUpgradeOptions.
+func (in *ClusterUpgradeOptions) DeepCopy() *ClusterUpgradeOptions {
+	if in == nil {
+		return nil
+	}
+	out := new(ClusterUpgradeOptions)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DeletionCondition) DeepCopyInto(out *DeletionCondition) {
+	*out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeletionCondition.
+func (in *DeletionCondition) DeepCopy() *DeletionCondition {
+	if in == nil {
+		return nil
+	}
+	out := new(DeletionCondition)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DeletionPolicy) DeepCopyInto(out *DeletionPolicy) {
+	*out = *in
+	if in.Policy != nil {
+		in, out := &in.Policy, &out.Policy
+		*out = new(DeletionPolicyType)
+		**out = **in
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeletionPolicy.
+func (in *DeletionPolicy) DeepCopy() *DeletionPolicy {
+	if in == nil {
+		return nil
+	}
+	out := new(DeletionPolicy)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DeletionRule) DeepCopyInto(out *DeletionRule) {
+	*out = *in
+	out.Condition = in.Condition
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeletionRule.
+func (in *DeletionRule) DeepCopy() *DeletionRule {
+	if in == nil {
+		return nil
+	}
+	out := new(DeletionRule)
+	in.DeepCopyInto(out)
+	return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *DeletionStrategy) DeepCopyInto(out *DeletionStrategy) {
+	*out = *in
+	if in.OnSuccess != nil {
+		in, out := &in.OnSuccess, &out.OnSuccess
+		*out = new(DeletionPolicy)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.OnFailure != nil {
+		in, out := &in.OnFailure, &out.OnFailure
+		*out = new(DeletionPolicy)
+		(*in).DeepCopyInto(*out)
+	}
+	if in.DeletionRules != nil {
+		in, out := &in.DeletionRules, &out.DeletionRules
+		*out = make([]DeletionRule, len(*in))
+		copy(*out, *in)
+	}
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeletionStrategy.
+func (in *DeletionStrategy) DeepCopy() *DeletionStrategy {
+	if in == nil {
+		return nil
+	}
+	out := new(DeletionStrategy)
+	in.DeepCopyInto(out)
+	return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *GcsFaultToleranceOptions) DeepCopyInto(out *GcsFaultToleranceOptions) {
 	*out = *in
@@ -142,6 +253,20 @@ func (in *HeadGroupSpec) DeepCopyInto(out *HeadGroupSpec) {
 		*out = new(bool)
 		**out = **in
 	}
+	if in.Resources != nil {
+		in, out := &in.Resources, &out.Resources
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.Labels != nil {
+		in, out := &in.Labels, &out.Labels
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
 	if in.RayStartParams != nil {
 		in, out := &in.RayStartParams, &out.RayStartParams
 		*out = make(map[string]string, len(*in))
@@ -441,10 +566,10 @@ func (in *RayJobSpec) DeepCopyInto(out *RayJobSpec) {
 		*out = new(string)
 		**out = **in
 	}
-	if in.DeletionPolicy != nil {
-		in, out := &in.DeletionPolicy, &out.DeletionPolicy
-		*out = new(DeletionPolicy)
-		**out = **in
+	if in.DeletionStrategy != nil {
+		in, out := &in.DeletionStrategy, &out.DeletionStrategy
+		*out = new(DeletionStrategy)
+		(*in).DeepCopyInto(*out)
 	}
 }
 
@@ -578,6 +703,11 @@ func (in *RayServiceList) DeepCopyObject() runtime.Object {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *RayServiceSpec) DeepCopyInto(out *RayServiceSpec) {
 	*out = *in
+	if in.RayClusterDeletionDelaySeconds != nil {
+		in, out := &in.RayClusterDeletionDelaySeconds, &out.RayClusterDeletionDelaySeconds
+		*out = new(int32)
+		**out = **in
+	}
 	if in.ServiceUnhealthySecondThreshold != nil {
 		in, out := &in.ServiceUnhealthySecondThreshold, &out.ServiceUnhealthySecondThreshold
 		*out = new(int32)
@@ -621,6 +751,20 @@ func (in *RayServiceStatus) DeepCopyInto(out *RayServiceStatus) {
 			(*out)[key] = *val.DeepCopy()
 		}
 	}
+	if in.TargetCapacity != nil {
+		in, out := &in.TargetCapacity, &out.TargetCapacity
+		*out = new(int32)
+		**out = **in
+	}
+	if in.TrafficRoutedPercent != nil {
+		in, out := &in.TrafficRoutedPercent, &out.TrafficRoutedPercent
+		*out = new(int32)
+		**out = **in
+	}
+	if in.LastTrafficMigratedTime != nil {
+		in, out := &in.LastTrafficMigratedTime, &out.LastTrafficMigratedTime
+		*out = (*in).DeepCopy()
+	}
 	in.RayClusterStatus.DeepCopyInto(&out.RayClusterStatus)
 }
 
@@ -670,6 +814,11 @@ func (in *RayServiceUpgradeStrategy) DeepCopyInto(out *RayServiceUpgradeStrategy
 		*out = new(RayServiceUpgradeType)
 		**out = **in
 	}
+	if in.ClusterUpgradeOptions != nil {
+		in, out := &in.ClusterUpgradeOptions, &out.ClusterUpgradeOptions
+		*out = new(ClusterUpgradeOptions)
+		(*in).DeepCopyInto(*out)
+	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RayServiceUpgradeStrategy.
@@ -785,6 +934,20 @@ func (in *WorkerGroupSpec) DeepCopyInto(out *WorkerGroupSpec) {
 		*out = new(int32)
 		**out = **in
 	}
+	if in.Resources != nil {
+		in, out := &in.Resources, &out.Resources
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
+	if in.Labels != nil {
+		in, out := &in.Labels, &out.Labels
+		*out = make(map[string]string, len(*in))
+		for key, val := range *in {
+			(*out)[key] = val
+		}
+	}
 	if in.RayStartParams != nil {
 		in, out := &in.RayStartParams, &out.RayStartParams
 		*out = make(map[string]string, len(*in))
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/consistency.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/consistency.go
new file mode 100644
index 000000000..4d04e9f5e
--- /dev/null
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/consistency.go
@@ -0,0 +1,113 @@
+package utils
+
+import (
+	"reflect"
+
+	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
+	"github.com/ray-project/kuberay/ray-operator/pkg/features"
+)
+
+// Checks whether the old and new RayClusterStatus are inconsistent by comparing different fields. If the only
+// differences between the old and new status are the `LastUpdateTime` and `ObservedGeneration` fields, the
+// status update will not be triggered.
+//
+// TODO (kevin85421): The field `ObservedGeneration` is not being well-maintained at the moment. In the future,
+// this field should be used to determine whether to update this CR or not.
+func InconsistentRayClusterStatus(oldStatus rayv1.RayClusterStatus, newStatus rayv1.RayClusterStatus) bool {
+	if oldStatus.State != newStatus.State || oldStatus.Reason != newStatus.Reason {
+		return true
+	}
+	if oldStatus.ReadyWorkerReplicas != newStatus.ReadyWorkerReplicas ||
+		oldStatus.AvailableWorkerReplicas != newStatus.AvailableWorkerReplicas ||
+		oldStatus.DesiredWorkerReplicas != newStatus.DesiredWorkerReplicas ||
+		oldStatus.MinWorkerReplicas != newStatus.MinWorkerReplicas ||
+		oldStatus.MaxWorkerReplicas != newStatus.MaxWorkerReplicas {
+		return true
+	}
+	if !reflect.DeepEqual(oldStatus.Endpoints, newStatus.Endpoints) || !reflect.DeepEqual(oldStatus.Head, newStatus.Head) {
+		return true
+	}
+	if !reflect.DeepEqual(oldStatus.Conditions, newStatus.Conditions) {
+		return true
+	}
+	return false
+}
+
+// Checks whether the old and new RayServiceStatus are inconsistent by comparing different fields.
+// The RayClusterStatus field is only for observability in RayService CR, and changes to it will not trigger the status update.
+func inconsistentRayServiceStatus(oldStatus rayv1.RayServiceStatus, newStatus rayv1.RayServiceStatus) bool {
+	if oldStatus.RayClusterName != newStatus.RayClusterName {
+		return true
+	}
+
+	if len(oldStatus.Applications) != len(newStatus.Applications) {
+		return true
+	}
+
+	var ok bool
+	for appName, newAppStatus := range newStatus.Applications {
+		var oldAppStatus rayv1.AppStatus
+		if oldAppStatus, ok = oldStatus.Applications[appName]; !ok {
+			return true
+		}
+
+		if oldAppStatus.Status != newAppStatus.Status {
+			return true
+		} else if oldAppStatus.Message != newAppStatus.Message {
+			return true
+		}
+
+		if len(oldAppStatus.Deployments) != len(newAppStatus.Deployments) {
+			return true
+		}
+
+		for deploymentName, newDeploymentStatus := range newAppStatus.Deployments {
+			var oldDeploymentStatus rayv1.ServeDeploymentStatus
+			if oldDeploymentStatus, ok = oldAppStatus.Deployments[deploymentName]; !ok {
+				return true
+			}
+
+			if oldDeploymentStatus.Status != newDeploymentStatus.Status {
+				return true
+			} else if oldDeploymentStatus.Message != newDeploymentStatus.Message {
+				return true
+			}
+		}
+	}
+
+	if features.Enabled(features.RayServiceIncrementalUpgrade) {
+		// Also check for changes in IncrementalUpgrade related Status fields.
+		if oldStatus.TrafficRoutedPercent != newStatus.TrafficRoutedPercent ||
+			oldStatus.TargetCapacity != newStatus.TargetCapacity ||
+			oldStatus.LastTrafficMigratedTime != newStatus.LastTrafficMigratedTime {
+			return true
+		}
+	}
+
+	return false
+}
+
+// Determine whether to update the status of the RayService instance.
+func InconsistentRayServiceStatuses(oldStatus rayv1.RayServiceStatuses, newStatus rayv1.RayServiceStatuses) bool {
+	if oldStatus.ServiceStatus != newStatus.ServiceStatus {
+		return true
+	}
+
+	if oldStatus.NumServeEndpoints != newStatus.NumServeEndpoints {
+		return true
+	}
+
+	if !reflect.DeepEqual(oldStatus.Conditions, newStatus.Conditions) {
+		return true
+	}
+
+	if inconsistentRayServiceStatus(oldStatus.ActiveServiceStatus, newStatus.ActiveServiceStatus) {
+		return true
+	}
+
+	if inconsistentRayServiceStatus(oldStatus.PendingServiceStatus, newStatus.PendingServiceStatus) {
+		return true
+	}
+
+	return false
+}
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/constant.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/constant.go
index 321320c0b..7d2f36297 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/constant.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/constant.go
@@ -27,14 +27,28 @@ const (
 	NumWorkerGroupsKey                       = "ray.io/num-worker-groups"
 	KubeRayVersion                           = "ray.io/kuberay-version"
 
+	// Labels for feature RayMultihostIndexing
+	//
+	// RayWorkerReplicaNameKey label is the unique name for the replica in a specific worker group. It is made up
+	// of the worker group name and a unique identifier (e.g. multi-host-worker-group-xh3hf). This label is unique
+	// across RayClusters.
+	RayWorkerReplicaNameKey = "ray.io/worker-group-replica-name"
+
+	// RayWorkerReplicaIndexKey label is the integer index for the replica in it's worker group (0 to replicas-1).
+	// The value for this label is unique within its worker group, but not across worker groups or RayClusters.
+	RayWorkerReplicaIndexKey = "ray.io/worker-group-replica-index"
+
+	// RayHostIndexKey label represents the index of the host within the replica group.
+	RayHostIndexKey = "ray.io/replica-host-index"
+
 	// In KubeRay, the Ray container must be the first application container in a head or worker Pod.
 	RayContainerIndex = 0
 
 	// Batch scheduling labels
 	// TODO(tgaddair): consider making these part of the CRD
-	RaySchedulerName                = "ray.io/scheduler-name"
-	RayPriorityClassName            = "ray.io/priority-class-name"
-	RayClusterGangSchedulingEnabled = "ray.io/gang-scheduling-enabled"
+	RaySchedulerName         = "ray.io/scheduler-name"
+	RayPriorityClassName     = "ray.io/priority-class-name"
+	RayGangSchedulingEnabled = "ray.io/gang-scheduling-enabled"
 
 	// Ray GCS FT related annotations
 	RayFTEnabledAnnotationKey         = "ray.io/ft-enabled"
@@ -45,6 +59,22 @@ const (
 	// `KUBERAY_GEN_RAY_START_CMD`.
 	RayOverwriteContainerCmdAnnotationKey = "ray.io/overwrite-container-cmd"
 
+	// RayServiceInitializingTimeoutAnnotation specifies the timeout for RayService initialization.
+	// Accepts Go duration format (e.g., "30m", "1h") or integer seconds.
+	//
+	// Behavior when timeout is exceeded:
+	//   - RayServiceReady condition is set to False with reason InitializingTimeout
+	//   - RayService enters a terminal failure state (cannot be recovered by spec updates)
+	//   - Cluster names are cleared, triggering cleanup of RayCluster resources
+	//   - A Warning event is emitted with timeout details
+	//
+	// Recovery after timeout:
+	//   The RayService must be deleted and recreated. Updating the spec will NOT retry initialization.
+	RayServiceInitializingTimeoutAnnotation = "ray.io/initializing-timeout"
+
+	// RayJob default cluster selector key
+	RayJobClusterSelectorKey = "ray.io/cluster"
+
 	// Finalizers for GCS fault tolerance
 	GCSFaultToleranceRedisCleanupFinalizer = "ray.io/gcs-ft-redis-cleanup-finalizer"
 
@@ -76,6 +106,10 @@ const (
 	MetricsPortName   = "metrics"
 	ServingPortName   = "serve"
 
+	// Gateway defaults for HTTP protocol
+	GatewayListenerPortName    = "http"
+	DefaultGatewayListenerPort = 80
+
 	// The default AppProtocol for Kubernetes service
 	DefaultServiceAppProtocol = "tcp"
 
@@ -164,6 +198,9 @@ const (
 	// by default starting with v1.4.0.
 	ENABLE_LOGIN_SHELL = "ENABLE_LOGIN_SHELL"
 
+	// If set to true, we will use deterministic name for head pod. Otherwise, the non-deterministic name is used.
+	ENABLE_DETERMINISTIC_HEAD_POD_NAME = "ENABLE_DETERMINISTIC_HEAD_POD_NAME"
+
 	// Ray core default configurations
 	DefaultWorkerRayGcsReconnectTimeoutS = "600"
 
@@ -201,13 +238,17 @@ const (
 	RayJobStopJobFinalizer = "ray.io/rayjob-finalizer"
 
 	// RayNodeHeadGroupLabelValue is the value for the RayNodeGroupLabelKey label on a head node
-	RayNodeHeadGroupLabelValue = "headgroup"
+	RayNodeHeadGroupLabelValue      = "headgroup"
+	RayNodeSubmitterGroupLabelValue = "submittergroup"
+
+	// SubmitterContainerName is the default name of the job submit container injected into the head Pod in SidecarMode.
+	SubmitterContainerName = "ray-job-submitter"
 
 	// KUBERAY_VERSION is the build version of KubeRay.
 	// The version is included in the RAY_USAGE_STATS_EXTRA_TAGS environment variable
 	// as well as the user-agent. This constant is updated before release.
 	// TODO: Update KUBERAY_VERSION to be a build-time variable.
-	KUBERAY_VERSION = "v1.4.2"
+	KUBERAY_VERSION = "v1.5.0"
 
 	// KubeRayController represents the value of the default job controller
 	KubeRayController = "ray.io/kuberay-operator"
@@ -303,14 +344,26 @@ const (
 	FailedToCreateRayCluster      K8sEventType = "FailedToCreateRayCluster"
 	FailedToDeleteRayCluster      K8sEventType = "FailedToDeleteRayCluster"
 	FailedToUpdateRayCluster      K8sEventType = "FailedToUpdateRayCluster"
+	RayClusterNotFound            K8sEventType = "RayClusterNotFound"
 
 	// RayService event list
+	CreatedGateway                  K8sEventType = "CreatedGateway"
+	CreatedHTTPRoute                K8sEventType = "CreatedHTTPRoute"
 	InvalidRayServiceSpec           K8sEventType = "InvalidRayServiceSpec"
 	InvalidRayServiceMetadata       K8sEventType = "InvalidRayServiceMetadata"
+	RayServiceInitializingTimeout   K8sEventType = "RayServiceInitializingTimeout"
 	UpdatedHeadPodServeLabel        K8sEventType = "UpdatedHeadPodServeLabel"
+	UpdatedGateway                  K8sEventType = "UpdatedGateway"
+	UpdatedHTTPRoute                K8sEventType = "UpdatedHTTPRoute"
 	UpdatedServeApplications        K8sEventType = "UpdatedServeApplications"
+	UpdatedServeTargetCapacity      K8sEventType = "UpdatedServeTargetCapacity"
 	FailedToUpdateHeadPodServeLabel K8sEventType = "FailedToUpdateHeadPodServeLabel"
 	FailedToUpdateServeApplications K8sEventType = "FailedToUpdateServeApplications"
+	FailedToUpdateTargetCapacity    K8sEventType = "FailedToUpdateTargetCapacity"
+	FailedToCreateGateway           K8sEventType = "FailedToCreateGateway"
+	FailedToUpdateGateway           K8sEventType = "FailedToUpdateGateway"
+	FailedToCreateHTTPRoute         K8sEventType = "FailedToCreateHTTPRoute"
+	FailedToUpdateHTTPRoute         K8sEventType = "FailedToUpdateHTTPRoute"
 
 	// Generic Pod event list
 	DeletedPod                  K8sEventType = "DeletedPod"
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboard_httpclient.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboardclient/dashboard_httpclient.go
similarity index 50%
rename from vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboard_httpclient.go
rename to vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboardclient/dashboard_httpclient.go
index d689e216b..d360ebc0a 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboard_httpclient.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboardclient/dashboard_httpclient.go
@@ -1,4 +1,4 @@
-package utils
+package dashboardclient
 
 import (
 	"bytes"
@@ -6,130 +6,49 @@ import (
 	"fmt"
 	"io"
 	"net/http"
-	"time"
+	"net/url"
+	"strings"
 
-	fmtErrors "github.com/pkg/errors"
-	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/errors"
 	"k8s.io/apimachinery/pkg/util/json"
 	"k8s.io/apimachinery/pkg/util/yaml"
-	ctrl "sigs.k8s.io/controller-runtime"
-	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
+	utiltypes "github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types"
 )
 
 var (
 	// Multi-application URL paths
 	ServeDetailsPath = "/api/serve/applications/"
+	APITypeParam     = "declarative"
 	DeployPathV2     = "/api/serve/applications/"
 	// Job URL paths
 	JobPath = "/api/jobs/"
 )
 
 type RayDashboardClientInterface interface {
-	InitClient(ctx context.Context, url string, rayCluster *rayv1.RayCluster) error
+	InitClient(client *http.Client, dashboardURL string)
 	UpdateDeployments(ctx context.Context, configJson []byte) error
 	// V2/multi-app Rest API
-	GetServeDetails(ctx context.Context) (*ServeDetails, error)
-	GetMultiApplicationStatus(context.Context) (map[string]*ServeApplicationStatus, error)
-	GetJobInfo(ctx context.Context, jobId string) (*RayJobInfo, error)
-	ListJobs(ctx context.Context) (*[]RayJobInfo, error)
+	GetServeDetails(ctx context.Context) (*utiltypes.ServeDetails, error)
+	GetMultiApplicationStatus(context.Context) (map[string]*utiltypes.ServeApplicationStatus, error)
+	GetJobInfo(ctx context.Context, jobId string) (*utiltypes.RayJobInfo, error)
+	ListJobs(ctx context.Context) (*[]utiltypes.RayJobInfo, error)
 	SubmitJob(ctx context.Context, rayJob *rayv1.RayJob) (string, error)
-	SubmitJobReq(ctx context.Context, request *RayJobRequest, name *string) (string, error)
+	SubmitJobReq(ctx context.Context, request *utiltypes.RayJobRequest) (string, error)
 	GetJobLog(ctx context.Context, jobName string) (*string, error)
 	StopJob(ctx context.Context, jobName string) error
 	DeleteJob(ctx context.Context, jobName string) error
 }
 
-type BaseDashboardClient struct {
+type RayDashboardClient struct {
 	client       *http.Client
 	dashboardURL string
 }
 
-func GetRayDashboardClientFunc(mgr ctrl.Manager, useKubernetesProxy bool) func() RayDashboardClientInterface {
-	return func() RayDashboardClientInterface {
-		return &RayDashboardClient{
-			mgr:                mgr,
-			useKubernetesProxy: useKubernetesProxy,
-		}
-	}
-}
-
-type RayDashboardClient struct {
-	mgr ctrl.Manager
-	BaseDashboardClient
-	useKubernetesProxy bool
-}
-
-// FetchHeadServiceURL fetches the URL that consists of the FQDN for the RayCluster's head service
-// and the port with the given port name (defaultPortName).
-func FetchHeadServiceURL(ctx context.Context, cli client.Client, rayCluster *rayv1.RayCluster, defaultPortName string) (string, error) {
-	log := ctrl.LoggerFrom(ctx)
-	headSvc := &corev1.Service{}
-	headSvcName, err := GenerateHeadServiceName(RayClusterCRD, rayCluster.Spec, rayCluster.Name)
-	if err != nil {
-		log.Error(err, "Failed to generate head service name", "RayCluster name", rayCluster.Name, "RayCluster spec", rayCluster.Spec)
-		return "", err
-	}
-
-	if err = cli.Get(ctx, client.ObjectKey{Name: headSvcName, Namespace: rayCluster.Namespace}, headSvc); err != nil {
-		if errors.IsNotFound(err) {
-			log.Error(err, "Head service is not found", "head service name", headSvcName, "namespace", rayCluster.Namespace)
-		}
-		return "", err
-	}
-
-	log.Info("FetchHeadServiceURL", "head service name", headSvc.Name, "namespace", headSvc.Namespace)
-	servicePorts := headSvc.Spec.Ports
-	port := int32(-1)
-
-	for _, servicePort := range servicePorts {
-		if servicePort.Name == defaultPortName {
-			port = servicePort.Port
-			break
-		}
-	}
-
-	if port == int32(-1) {
-		return "", fmtErrors.Errorf("%s port is not found", defaultPortName)
-	}
-
-	domainName := GetClusterDomainName()
-	headServiceURL := fmt.Sprintf("%s.%s.svc.%s:%v",
-		headSvc.Name,
-		headSvc.Namespace,
-		domainName,
-		port)
-	log.Info("FetchHeadServiceURL", "head service URL", headServiceURL)
-	return headServiceURL, nil
-}
-
-func (r *RayDashboardClient) InitClient(ctx context.Context, url string, rayCluster *rayv1.RayCluster) error {
-	log := ctrl.LoggerFrom(ctx)
-
-	if r.useKubernetesProxy {
-		var err error
-		headSvcName := rayCluster.Status.Head.ServiceName
-		if headSvcName == "" {
-			log.Info("RayCluster is missing .status.head.serviceName, calling GenerateHeadServiceName instead...", "RayCluster name", rayCluster.Name, "namespace", rayCluster.Namespace)
-			headSvcName, err = GenerateHeadServiceName(RayClusterCRD, rayCluster.Spec, rayCluster.Name)
-			if err != nil {
-				return err
-			}
-		}
-
-		r.client = r.mgr.GetHTTPClient()
-		r.dashboardURL = fmt.Sprintf("%s/api/v1/namespaces/%s/services/%s:dashboard/proxy", r.mgr.GetConfig().Host, rayCluster.Namespace, headSvcName)
-		return nil
-	}
-
-	r.client = &http.Client{
-		Timeout: 2 * time.Second,
-	}
-
-	r.dashboardURL = "http://" + url
-	return nil
+func (r *RayDashboardClient) InitClient(client *http.Client, dashboardURL string) {
+	r.client = client
+	r.dashboardURL = dashboardURL
 }
 
 // UpdateDeployments update the deployments in the Ray cluster.
@@ -148,7 +67,10 @@ func (r *RayDashboardClient) UpdateDeployments(ctx context.Context, configJson [
 	}
 	defer resp.Body.Close()
 
-	body, _ := io.ReadAll(resp.Body)
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return fmt.Errorf("failed to read response when updating deployments: %w", err)
+	}
 	if resp.StatusCode < 200 || resp.StatusCode > 299 {
 		return fmt.Errorf("UpdateDeployments fail: %s %s", resp.Status, string(body))
 	}
@@ -156,18 +78,26 @@ func (r *RayDashboardClient) UpdateDeployments(ctx context.Context, configJson [
 	return nil
 }
 
-func (r *RayDashboardClient) GetMultiApplicationStatus(ctx context.Context) (map[string]*ServeApplicationStatus, error) {
+func (r *RayDashboardClient) GetMultiApplicationStatus(ctx context.Context) (map[string]*utiltypes.ServeApplicationStatus, error) {
 	serveDetails, err := r.GetServeDetails(ctx)
 	if err != nil {
-		return nil, fmt.Errorf("Failed to get serve details: %w", err)
+		return nil, fmt.Errorf("failed to get serve details: %w", err)
 	}
 
 	return r.ConvertServeDetailsToApplicationStatuses(serveDetails)
 }
 
-// GetServeDetails gets details on all live applications on the Ray cluster.
-func (r *RayDashboardClient) GetServeDetails(ctx context.Context) (*ServeDetails, error) {
-	req, err := http.NewRequestWithContext(ctx, "GET", r.dashboardURL+ServeDetailsPath, nil)
+// GetServeDetails gets details on all declarative applications on the Ray cluster.
+func (r *RayDashboardClient) GetServeDetails(ctx context.Context) (*utiltypes.ServeDetails, error) {
+	serveDetailsURL, err := url.Parse(r.dashboardURL + ServeDetailsPath)
+	if err != nil {
+		return nil, fmt.Errorf("failed to parse dashboard URL: %w", err)
+	}
+	q := serveDetailsURL.Query()
+	q.Set("api_type", APITypeParam)
+	serveDetailsURL.RawQuery = q.Encode()
+
+	req, err := http.NewRequestWithContext(ctx, "GET", serveDetailsURL.String(), nil)
 	if err != nil {
 		return nil, err
 	}
@@ -178,13 +108,16 @@ func (r *RayDashboardClient) GetServeDetails(ctx context.Context) (*ServeDetails
 	}
 	defer resp.Body.Close()
 
-	body, _ := io.ReadAll(resp.Body)
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return nil, fmt.Errorf("failed to read response when getting serve details: %w", err)
+	}
 
 	if resp.StatusCode < 200 || resp.StatusCode > 299 {
 		return nil, fmt.Errorf("GetServeDetails fail: %s %s", resp.Status, string(body))
 	}
 
-	var serveDetails ServeDetails
+	var serveDetails utiltypes.ServeDetails
 	if err = json.Unmarshal(body, &serveDetails); err != nil {
 		return nil, fmt.Errorf("GetServeDetails failed. Failed to unmarshal bytes: %s", string(body))
 	}
@@ -192,67 +125,24 @@ func (r *RayDashboardClient) GetServeDetails(ctx context.Context) (*ServeDetails
 	return &serveDetails, nil
 }
 
-func (r *RayDashboardClient) ConvertServeDetailsToApplicationStatuses(serveDetails *ServeDetails) (map[string]*ServeApplicationStatus, error) {
+func (r *RayDashboardClient) ConvertServeDetailsToApplicationStatuses(serveDetails *utiltypes.ServeDetails) (map[string]*utiltypes.ServeApplicationStatus, error) {
 	detailsJson, err := json.Marshal(serveDetails.Applications)
 	if err != nil {
-		return nil, fmt.Errorf("Failed to marshal serve details: %v", serveDetails.Applications)
+		return nil, fmt.Errorf("failed to marshal serve details: %v", serveDetails.Applications)
 	}
 
-	applicationStatuses := map[string]*ServeApplicationStatus{}
+	applicationStatuses := map[string]*utiltypes.ServeApplicationStatus{}
 	if err = json.Unmarshal(detailsJson, &applicationStatuses); err != nil {
-		return nil, fmt.Errorf("Failed to unmarshal serve details bytes into map of application statuses: %w. Bytes: %s", err, string(detailsJson))
+		return nil, fmt.Errorf("failed to unmarshal serve details bytes into map of application statuses: %w. Bytes: %s", err, string(detailsJson))
 	}
 
 	return applicationStatuses, nil
 }
 
-type RuntimeEnvType map[string]interface{}
-
-// RayJobInfo is the response of "ray job status" api.
-// Reference to https://docs.ray.io/en/latest/cluster/running-applications/job-submission/rest.html#ray-job-rest-api-spec
-// Reference to https://github.com/ray-project/ray/blob/cfbf98c315cfb2710c56039a3c96477d196de049/dashboard/modules/job/pydantic_models.py#L38-L107
-type RayJobInfo struct {
-	ErrorType    *string           `json:"error_type,omitempty"`
-	Metadata     map[string]string `json:"metadata,omitempty"`
-	RuntimeEnv   RuntimeEnvType    `json:"runtime_env,omitempty"`
-	JobStatus    rayv1.JobStatus   `json:"status,omitempty"`
-	Entrypoint   string            `json:"entrypoint,omitempty"`
-	JobId        string            `json:"job_id,omitempty"`
-	SubmissionId string            `json:"submission_id,omitempty"`
-	Message      string            `json:"message,omitempty"`
-	StartTime    uint64            `json:"start_time,omitempty"`
-	EndTime      uint64            `json:"end_time,omitempty"`
-}
-
-// RayJobRequest is the request body to submit.
-// Reference to https://docs.ray.io/en/latest/cluster/running-applications/job-submission/rest.html#ray-job-rest-api-spec
-// Reference to https://github.com/ray-project/ray/blob/cfbf98c315cfb2710c56039a3c96477d196de049/dashboard/modules/job/common.py#L325-L353
-type RayJobRequest struct {
-	RuntimeEnv   RuntimeEnvType     `json:"runtime_env,omitempty"`
-	Metadata     map[string]string  `json:"metadata,omitempty"`
-	Resources    map[string]float32 `json:"entrypoint_resources,omitempty"`
-	Entrypoint   string             `json:"entrypoint"`
-	SubmissionId string             `json:"submission_id,omitempty"`
-	NumCpus      float32            `json:"entrypoint_num_cpus,omitempty"`
-	NumGpus      float32            `json:"entrypoint_num_gpus,omitempty"`
-}
-
-type RayJobResponse struct {
-	JobId string `json:"job_id"`
-}
-
-type RayJobStopResponse struct {
-	Stopped bool `json:"stopped"`
-}
-
-type RayJobLogsResponse struct {
-	Logs string `json:"logs,omitempty"`
-}
-
 // Note that RayJobInfo and error can't be nil at the same time.
 // Please make sure if the Ray job with JobId can't be found. Return a BadRequest error.
-func (r *RayDashboardClient) GetJobInfo(ctx context.Context, jobId string) (*RayJobInfo, error) {
-	req, err := http.NewRequestWithContext(ctx, "GET", r.dashboardURL+JobPath+jobId, nil)
+func (r *RayDashboardClient) GetJobInfo(ctx context.Context, jobId string) (*utiltypes.RayJobInfo, error) {
+	req, err := http.NewRequestWithContext(ctx, http.MethodGet, r.dashboardURL+JobPath+jobId, nil)
 	if err != nil {
 		return nil, err
 	}
@@ -269,10 +159,10 @@ func (r *RayDashboardClient) GetJobInfo(ctx context.Context, jobId string) (*Ray
 
 	body, err := io.ReadAll(resp.Body)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to read response when getting job info: %w", err)
 	}
 
-	var jobInfo RayJobInfo
+	var jobInfo utiltypes.RayJobInfo
 	if err = json.Unmarshal(body, &jobInfo); err != nil {
 		// Maybe body is not valid json, raise an error with the body.
 		return nil, fmt.Errorf("GetJobInfo fail: %s", string(body))
@@ -281,8 +171,8 @@ func (r *RayDashboardClient) GetJobInfo(ctx context.Context, jobId string) (*Ray
 	return &jobInfo, nil
 }
 
-func (r *RayDashboardClient) ListJobs(ctx context.Context) (*[]RayJobInfo, error) {
-	req, err := http.NewRequestWithContext(ctx, "GET", r.dashboardURL+JobPath, nil)
+func (r *RayDashboardClient) ListJobs(ctx context.Context) (*[]utiltypes.RayJobInfo, error) {
+	req, err := http.NewRequestWithContext(ctx, http.MethodGet, r.dashboardURL+JobPath, nil)
 	if err != nil {
 		return nil, err
 	}
@@ -299,10 +189,10 @@ func (r *RayDashboardClient) ListJobs(ctx context.Context) (*[]RayJobInfo, error
 
 	body, err := io.ReadAll(resp.Body)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to read response when listing jobs: %w", err)
 	}
 
-	var jobInfo []RayJobInfo
+	var jobInfo []utiltypes.RayJobInfo
 	if err = json.Unmarshal(body, &jobInfo); err != nil {
 		// Maybe body is not valid json, raise an error with the body.
 		return nil, fmt.Errorf("GetJobInfo fail: %s", string(body))
@@ -316,18 +206,14 @@ func (r *RayDashboardClient) SubmitJob(ctx context.Context, rayJob *rayv1.RayJob
 	if err != nil {
 		return "", err
 	}
-	return r.SubmitJobReq(ctx, request, &rayJob.Name)
+	return r.SubmitJobReq(ctx, request)
 }
 
-func (r *RayDashboardClient) SubmitJobReq(ctx context.Context, request *RayJobRequest, name *string) (jobId string, err error) {
-	log := ctrl.LoggerFrom(ctx)
+func (r *RayDashboardClient) SubmitJobReq(ctx context.Context, request *utiltypes.RayJobRequest) (jobId string, err error) {
 	rayJobJson, err := json.Marshal(request)
 	if err != nil {
 		return
 	}
-	if name != nil {
-		log.Info("Submit a ray job", "rayJob", name, "jobInfo", string(rayJobJson))
-	}
 
 	req, err := http.NewRequestWithContext(ctx, http.MethodPost, r.dashboardURL+JobPath, bytes.NewBuffer(rayJobJson))
 	if err != nil {
@@ -341,13 +227,20 @@ func (r *RayDashboardClient) SubmitJobReq(ctx context.Context, request *RayJobRe
 	}
 	defer resp.Body.Close()
 
-	body, _ := io.ReadAll(resp.Body)
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return "", fmt.Errorf("failed to read response when submitting job: %w", err)
+	}
 
 	if resp.StatusCode < 200 || resp.StatusCode > 299 {
+		// If the submission_id is already used, the dashboard will return status code 500; we return the submission_id directly.
+		if resp.StatusCode == http.StatusInternalServerError && strings.Contains(string(body), "Please use a different submission_id") {
+			return request.SubmissionId, fmt.Errorf("submission ID '%s' already used, Please use a different submission_id", request.SubmissionId)
+		}
 		return "", fmt.Errorf("SubmitJob fail: %s %s", resp.Status, string(body))
 	}
 
-	var jobResp RayJobResponse
+	var jobResp utiltypes.RayJobResponse
 	if err = json.Unmarshal(body, &jobResp); err != nil {
 		// Maybe body is not valid json, raise an error with the body.
 		return "", fmt.Errorf("SubmitJob fail: %s", string(body))
@@ -358,9 +251,6 @@ func (r *RayDashboardClient) SubmitJobReq(ctx context.Context, request *RayJobRe
 
 // Get Job Log
 func (r *RayDashboardClient) GetJobLog(ctx context.Context, jobName string) (*string, error) {
-	log := ctrl.LoggerFrom(ctx)
-	log.Info("Get ray job log", "rayJob", jobName)
-
 	req, err := http.NewRequestWithContext(ctx, http.MethodGet, r.dashboardURL+JobPath+jobName+"/logs", nil)
 	if err != nil {
 		return nil, err
@@ -379,10 +269,10 @@ func (r *RayDashboardClient) GetJobLog(ctx context.Context, jobName string) (*st
 
 	body, err := io.ReadAll(resp.Body)
 	if err != nil {
-		return nil, err
+		return nil, fmt.Errorf("failed to read response when getting job log: %w", err)
 	}
 
-	var jobLog RayJobLogsResponse
+	var jobLog utiltypes.RayJobLogsResponse
 	if err = json.Unmarshal(body, &jobLog); err != nil {
 		// Maybe body is not valid json, raise an error with the body.
 		return nil, fmt.Errorf("GetJobLog fail: %s", string(body))
@@ -392,9 +282,6 @@ func (r *RayDashboardClient) GetJobLog(ctx context.Context, jobName string) (*st
 }
 
 func (r *RayDashboardClient) StopJob(ctx context.Context, jobName string) (err error) {
-	log := ctrl.LoggerFrom(ctx)
-	log.Info("Stop a ray job", "rayJob", jobName)
-
 	req, err := http.NewRequestWithContext(ctx, http.MethodPost, r.dashboardURL+JobPath+jobName+"/stop", nil)
 	if err != nil {
 		return err
@@ -407,9 +294,12 @@ func (r *RayDashboardClient) StopJob(ctx context.Context, jobName string) (err e
 	}
 	defer resp.Body.Close()
 
-	body, _ := io.ReadAll(resp.Body)
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return fmt.Errorf("failed to read response when stopping job: %w", err)
+	}
 
-	var jobStopResp RayJobStopResponse
+	var jobStopResp utiltypes.RayJobStopResponse
 	if err = json.Unmarshal(body, &jobStopResp); err != nil {
 		return err
 	}
@@ -421,16 +311,13 @@ func (r *RayDashboardClient) StopJob(ctx context.Context, jobName string) (err e
 		}
 		// StopJob only returns an error when JobStatus is not in terminal states (STOPPED / SUCCEEDED / FAILED)
 		if !rayv1.IsJobTerminal(jobInfo.JobStatus) {
-			return fmt.Errorf("Failed to stopped job: %v", jobInfo)
+			return fmt.Errorf("failed to stop job: %v", jobInfo)
 		}
 	}
 	return nil
 }
 
 func (r *RayDashboardClient) DeleteJob(ctx context.Context, jobName string) error {
-	log := ctrl.LoggerFrom(ctx)
-	log.Info("Delete a ray job", "rayJob", jobName)
-
 	req, err := http.NewRequestWithContext(ctx, http.MethodDelete, r.dashboardURL+JobPath+jobName, nil)
 	if err != nil {
 		return err
@@ -446,8 +333,8 @@ func (r *RayDashboardClient) DeleteJob(ctx context.Context, jobName string) erro
 	return nil
 }
 
-func ConvertRayJobToReq(rayJob *rayv1.RayJob) (*RayJobRequest, error) {
-	req := &RayJobRequest{
+func ConvertRayJobToReq(rayJob *rayv1.RayJob) (*utiltypes.RayJobRequest, error) {
+	req := &utiltypes.RayJobRequest{
 		Entrypoint:   rayJob.Spec.Entrypoint,
 		SubmissionId: rayJob.Status.JobId,
 		Metadata:     rayJob.Spec.Metadata,
@@ -469,8 +356,8 @@ func ConvertRayJobToReq(rayJob *rayv1.RayJob) (*RayJobRequest, error) {
 	return req, nil
 }
 
-func UnmarshalRuntimeEnvYAML(runtimeEnvYAML string) (RuntimeEnvType, error) {
-	var runtimeEnv RuntimeEnvType
+func UnmarshalRuntimeEnvYAML(runtimeEnvYAML string) (utiltypes.RuntimeEnvType, error) {
+	var runtimeEnv utiltypes.RuntimeEnvType
 	if err := yaml.Unmarshal([]byte(runtimeEnvYAML), &runtimeEnv); err != nil {
 		return nil, fmt.Errorf("failed to unmarshal RuntimeEnvYAML: %v: %w", runtimeEnvYAML, err)
 	}
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/fake_httpproxy_httpclient.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/fake_httpproxy_httpclient.go
index ccd0f99bd..90a39db25 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/fake_httpproxy_httpclient.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/fake_httpproxy_httpclient.go
@@ -9,10 +9,6 @@ type FakeRayHttpProxyClient struct {
 	IsHealthy bool
 }
 
-func (fc *FakeRayHttpProxyClient) InitClient() {}
-
-func (fc *FakeRayHttpProxyClient) SetHostIp(_, _, _ string, _ int) {}
-
 func (fc *FakeRayHttpProxyClient) CheckProxyActorHealth(_ context.Context) error {
 	if !fc.IsHealthy {
 		return fmt.Errorf("fake proxy actor is not healthy")
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/fake_serve_httpclient.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/fake_serve_httpclient.go
index 35de7ef86..1bf0588c4 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/fake_serve_httpclient.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/fake_serve_httpclient.go
@@ -7,54 +7,54 @@ import (
 	"sync/atomic"
 
 	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
+	"github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboardclient"
+	utiltypes "github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types"
 )
 
 type FakeRayDashboardClient struct {
-	multiAppStatuses map[string]*ServeApplicationStatus
-	GetJobInfoMock   atomic.Pointer[func(context.Context, string) (*RayJobInfo, error)]
-	BaseDashboardClient
-	serveDetails ServeDetails
+	multiAppStatuses  map[string]*utiltypes.ServeApplicationStatus
+	GetJobInfoMock    atomic.Pointer[func(context.Context, string) (*utiltypes.RayJobInfo, error)]
+	serveDetails      utiltypes.ServeDetails
+	LastUpdatedConfig []byte
 }
 
-var _ RayDashboardClientInterface = (*FakeRayDashboardClient)(nil)
+var _ dashboardclient.RayDashboardClientInterface = (*FakeRayDashboardClient)(nil)
 
-func (r *FakeRayDashboardClient) InitClient(_ context.Context, url string, _ *rayv1.RayCluster) error {
-	r.client = &http.Client{}
-	r.dashboardURL = "http://" + url
-	return nil
+func (r *FakeRayDashboardClient) InitClient(_ *http.Client, _ string) {
 }
 
-func (r *FakeRayDashboardClient) UpdateDeployments(_ context.Context, _ []byte) error {
+func (r *FakeRayDashboardClient) UpdateDeployments(_ context.Context, configJson []byte) error {
+	r.LastUpdatedConfig = configJson
 	fmt.Print("UpdateDeployments fake succeeds.")
 	return nil
 }
 
-func (r *FakeRayDashboardClient) GetMultiApplicationStatus(_ context.Context) (map[string]*ServeApplicationStatus, error) {
+func (r *FakeRayDashboardClient) GetMultiApplicationStatus(_ context.Context) (map[string]*utiltypes.ServeApplicationStatus, error) {
 	return r.multiAppStatuses, nil
 }
 
-func (r *FakeRayDashboardClient) GetServeDetails(_ context.Context) (*ServeDetails, error) {
+func (r *FakeRayDashboardClient) GetServeDetails(_ context.Context) (*utiltypes.ServeDetails, error) {
 	return &r.serveDetails, nil
 }
 
-func (r *FakeRayDashboardClient) SetMultiApplicationStatuses(statuses map[string]*ServeApplicationStatus) {
+func (r *FakeRayDashboardClient) SetMultiApplicationStatuses(statuses map[string]*utiltypes.ServeApplicationStatus) {
 	r.multiAppStatuses = statuses
 }
 
-func (r *FakeRayDashboardClient) GetJobInfo(ctx context.Context, jobId string) (*RayJobInfo, error) {
+func (r *FakeRayDashboardClient) GetJobInfo(ctx context.Context, jobId string) (*utiltypes.RayJobInfo, error) {
 	if mock := r.GetJobInfoMock.Load(); mock != nil {
 		return (*mock)(ctx, jobId)
 	}
-	return &RayJobInfo{JobStatus: rayv1.JobStatusRunning}, nil
+	return &utiltypes.RayJobInfo{JobStatus: rayv1.JobStatusRunning}, nil
 }
 
-func (r *FakeRayDashboardClient) ListJobs(ctx context.Context) (*[]RayJobInfo, error) {
+func (r *FakeRayDashboardClient) ListJobs(ctx context.Context) (*[]utiltypes.RayJobInfo, error) {
 	if mock := r.GetJobInfoMock.Load(); mock != nil {
 		info, err := (*mock)(ctx, "job_id")
 		if err != nil {
 			return nil, err
 		}
-		return &[]RayJobInfo{*info}, nil
+		return &[]utiltypes.RayJobInfo{*info}, nil
 	}
 	return nil, nil
 }
@@ -63,7 +63,7 @@ func (r *FakeRayDashboardClient) SubmitJob(_ context.Context, _ *rayv1.RayJob) (
 	return "", nil
 }
 
-func (r *FakeRayDashboardClient) SubmitJobReq(_ context.Context, _ *RayJobRequest, _ *string) (string, error) {
+func (r *FakeRayDashboardClient) SubmitJobReq(_ context.Context, _ *utiltypes.RayJobRequest) (string, error) {
 	return "", nil
 }
 
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/httpproxy_httpclient.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/httpproxy_httpclient.go
index 2436f8d4f..e9c53b381 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/httpproxy_httpclient.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/httpproxy_httpclient.go
@@ -6,30 +6,15 @@ import (
 	"io"
 	"net/http"
 	"time"
-
-	ctrl "sigs.k8s.io/controller-runtime"
 )
 
 type RayHttpProxyClientInterface interface {
-	InitClient()
 	CheckProxyActorHealth(ctx context.Context) error
-	SetHostIp(hostIp, podNamespace, podName string, port int)
-}
-
-func GetRayHttpProxyClientFunc(mgr ctrl.Manager, useKubernetesProxy bool) func() RayHttpProxyClientInterface {
-	return func() RayHttpProxyClientInterface {
-		return &RayHttpProxyClient{
-			mgr:                mgr,
-			useKubernetesProxy: useKubernetesProxy,
-		}
-	}
 }
 
 type RayHttpProxyClient struct {
-	client             *http.Client
-	mgr                ctrl.Manager
-	httpProxyURL       string
-	useKubernetesProxy bool
+	client       *http.Client
+	httpProxyURL string
 }
 
 func (r *RayHttpProxyClient) InitClient() {
@@ -38,15 +23,6 @@ func (r *RayHttpProxyClient) InitClient() {
 	}
 }
 
-func (r *RayHttpProxyClient) SetHostIp(hostIp, podNamespace, podName string, port int) {
-	if r.useKubernetesProxy {
-		r.client = r.mgr.GetHTTPClient()
-		r.httpProxyURL = fmt.Sprintf("%s/api/v1/namespaces/%s/pods/%s:%d/proxy/", r.mgr.GetConfig().Host, podNamespace, podName, port)
-	}
-
-	r.httpProxyURL = fmt.Sprintf("http://%s:%d/", hostIp, port)
-}
-
 // CheckProxyActorHealth checks the health status of the Ray Serve proxy actor.
 func (r *RayHttpProxyClient) CheckProxyActorHealth(ctx context.Context) error {
 	req, err := http.NewRequestWithContext(ctx, http.MethodGet, r.httpProxyURL+RayServeProxyHealthPath, nil)
@@ -59,11 +35,17 @@ func (r *RayHttpProxyClient) CheckProxyActorHealth(ctx context.Context) error {
 	}
 	defer resp.Body.Close()
 
-	body, _ := io.ReadAll(resp.Body)
-	if resp.StatusCode != 200 {
-		err := fmt.Errorf("CheckProxyActorHealth fails. status code: %d, status: %s, body: %s", resp.StatusCode, resp.Status, string(body))
+	if resp.StatusCode != http.StatusOK {
+		body, err := io.ReadAll(resp.Body)
+		if err != nil {
+			return fmt.Errorf("CheckProxyActorHealth fails. status code: %d, status: %s, error reading body: %w", resp.StatusCode, resp.Status, err)
+		}
+		err = fmt.Errorf("CheckProxyActorHealth fails. status code: %d, status: %s, body: %s", resp.StatusCode, resp.Status, string(body))
 		return err
 	}
+	// For responses with status code 200, we don't need to allocate memory for the response body.
+	// Instead, we discard the contents directly to avoid unnecessary memory allocations.
+	_, _ = io.Copy(io.Discard, resp.Body)
 
 	return nil
 }
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/resources.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/resources.go
new file mode 100644
index 000000000..c91edd748
--- /dev/null
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/resources.go
@@ -0,0 +1,17 @@
+package utils
+
+import (
+	"regexp"
+	"strings"
+)
+
+func IsGPUResourceKey(key string) bool {
+	// ending with "gpu" like "nvidia.com/gpu"
+	if strings.HasSuffix(key, "gpu") {
+		return true
+	}
+	// Nvidia Multi-Instance GPU in the form of "nvidia.com/mig-<slice_count>g.<memory_size>gb" like "nvidia.com/mig-2g.32gb"
+	// reference: https://github.com/NVIDIA/k8s-device-plugin#configuration-option-details
+	match, _ := regexp.MatchString(`nvidia\.com/mig-\d+g\.\d+gb$`, key)
+	return match
+}
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types/dashboard_httpclient.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types/dashboard_httpclient.go
new file mode 100644
index 000000000..a246ea399
--- /dev/null
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types/dashboard_httpclient.go
@@ -0,0 +1,48 @@
+package types
+
+import (
+	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
+)
+
+type RuntimeEnvType map[string]interface{}
+
+// RayJobInfo is the response of "ray job status" api.
+// Reference to https://docs.ray.io/en/latest/cluster/running-applications/job-submission/rest.html#ray-job-rest-api-spec
+// Reference to https://github.com/ray-project/ray/blob/cfbf98c315cfb2710c56039a3c96477d196de049/dashboard/modules/job/pydantic_models.py#L38-L107
+type RayJobInfo struct {
+	ErrorType    *string           `json:"error_type,omitempty"`
+	Metadata     map[string]string `json:"metadata,omitempty"`
+	RuntimeEnv   RuntimeEnvType    `json:"runtime_env,omitempty"`
+	JobStatus    rayv1.JobStatus   `json:"status,omitempty"`
+	Entrypoint   string            `json:"entrypoint,omitempty"`
+	JobId        string            `json:"job_id,omitempty"`
+	SubmissionId string            `json:"submission_id,omitempty"`
+	Message      string            `json:"message,omitempty"`
+	StartTime    uint64            `json:"start_time,omitempty"`
+	EndTime      uint64            `json:"end_time,omitempty"`
+}
+
+// RayJobRequest is the request body to submit.
+// Reference to https://docs.ray.io/en/latest/cluster/running-applications/job-submission/rest.html#ray-job-rest-api-spec
+// Reference to https://github.com/ray-project/ray/blob/cfbf98c315cfb2710c56039a3c96477d196de049/dashboard/modules/job/common.py#L325-L353
+type RayJobRequest struct {
+	RuntimeEnv   RuntimeEnvType     `json:"runtime_env,omitempty"`
+	Metadata     map[string]string  `json:"metadata,omitempty"`
+	Resources    map[string]float32 `json:"entrypoint_resources,omitempty"`
+	Entrypoint   string             `json:"entrypoint"`
+	SubmissionId string             `json:"submission_id,omitempty"`
+	NumCpus      float32            `json:"entrypoint_num_cpus,omitempty"`
+	NumGpus      float32            `json:"entrypoint_num_gpus,omitempty"`
+}
+
+type RayJobResponse struct {
+	JobId string `json:"job_id"`
+}
+
+type RayJobStopResponse struct {
+	Stopped bool `json:"stopped"`
+}
+
+type RayJobLogsResponse struct {
+	Logs string `json:"logs,omitempty"`
+}
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/serve_api_models.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types/serve_api_models.go
similarity index 99%
rename from vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/serve_api_models.go
rename to vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types/serve_api_models.go
index 33d4129e3..a6b1af09e 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/serve_api_models.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types/serve_api_models.go
@@ -1,4 +1,4 @@
-package utils
+package types
 
 // Please see the Ray Serve docs
 // https://docs.ray.io/en/latest/serve/api/doc/ray.serve.schema.ServeDeploySchema.html for the
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/util.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/util.go
index 495e90a82..540162bf9 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/util.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/util.go
@@ -6,23 +6,31 @@ import (
 	"encoding/base32"
 	"fmt"
 	"math"
+	"net/http"
 	"os"
 	"reflect"
 	"strconv"
 	"strings"
+	"time"
 	"unicode"
 
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
+	meta "k8s.io/apimachinery/pkg/api/meta"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/util/json"
 	"k8s.io/apimachinery/pkg/util/rand"
 	"k8s.io/client-go/discovery"
+	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
+	gwv1 "sigs.k8s.io/gateway-api/apis/v1"
 
 	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
+	"github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboardclient"
+	"github.com/ray-project/kuberay/ray-operator/pkg/features"
 )
 
 const (
@@ -266,7 +274,7 @@ func GetNamespace(metaData metav1.ObjectMeta) string {
 // @param ownerName: The name of the CR that owns the head service.
 func GenerateHeadServiceName(crdType CRDType, clusterSpec rayv1.RayClusterSpec, ownerName string) (string, error) {
 	switch crdType {
-	case RayServiceCRD:
+	case RayServiceCRD, RayJobCRD:
 		return fmt.Sprintf("%s-%s-%s", ownerName, rayv1.HeadNode, "svc"), nil
 	case RayClusterCRD:
 		headSvcName := fmt.Sprintf("%s-%s-%s", ownerName, rayv1.HeadNode, "svc")
@@ -326,6 +334,12 @@ func GenerateRayJobId(rayjob string) string {
 	return fmt.Sprintf("%s-%s", rayjob, rand.String(5))
 }
 
+// GenerateRayWorkerReplicaGroupName generates a name for the replica group
+// currently used for RayMultiHostIndexing
+func GenerateRayWorkerReplicaGroupName(workerGroupName string) string {
+	return fmt.Sprintf("%s-%s", workerGroupName, rand.String(5))
+}
+
 // GenerateIdentifier generates identifier of same group pods
 func GenerateIdentifier(clusterName string, nodeType rayv1.RayNodeType) string {
 	return fmt.Sprintf("%s-%s", clusterName, nodeType)
@@ -436,7 +450,7 @@ func CalculateDesiredResources(cluster *rayv1.RayCluster) corev1.ResourceList {
 			desiredResourcesList = append(desiredResourcesList, podResource)
 		}
 	}
-	return sumResourceList(desiredResourcesList)
+	return SumResourceList(desiredResourcesList)
 }
 
 func CalculateMinResources(cluster *rayv1.RayCluster) corev1.ResourceList {
@@ -450,7 +464,7 @@ func CalculateMinResources(cluster *rayv1.RayCluster) corev1.ResourceList {
 			minResourcesList = append(minResourcesList, podResource)
 		}
 	}
-	return sumResourceList(minResourcesList)
+	return SumResourceList(minResourcesList)
 }
 
 // calculateReplicaResource adjusts the resource quantities in a given ResourceList
@@ -499,7 +513,7 @@ func ConvertResourceListToMapString(resourceList corev1.ResourceList) map[string
 	return result
 }
 
-func sumResourceList(list []corev1.ResourceList) corev1.ResourceList {
+func SumResourceList(list []corev1.ResourceList) corev1.ResourceList {
 	totalResource := corev1.ResourceList{}
 	for _, l := range list {
 		for name, quantity := range l {
@@ -595,10 +609,10 @@ func GenerateJsonHash(obj interface{}) (string, error) {
 // FindContainerPort searches for a specific port $portName in the container.
 // If the port is found in the container, the corresponding port is returned.
 // If the port is not found, the $defaultPort is returned instead.
-func FindContainerPort(container *corev1.Container, portName string, defaultPort int) int {
+func FindContainerPort(container *corev1.Container, portName string, defaultPort int32) int32 {
 	for _, port := range container.Ports {
 		if port.Name == portName {
-			return int(port.ContainerPort)
+			return port.ContainerPort
 		}
 	}
 	return defaultPort
@@ -637,8 +651,8 @@ func EnvVarByName(envName string, envVars []corev1.EnvVar) (corev1.EnvVar, bool)
 }
 
 type ClientProvider interface {
-	GetDashboardClient(mgr manager.Manager) func() RayDashboardClientInterface
-	GetHttpProxyClient(mgr manager.Manager) func() RayHttpProxyClientInterface
+	GetDashboardClient(mgr manager.Manager) func(rayCluster *rayv1.RayCluster, url string) (dashboardclient.RayDashboardClientInterface, error)
+	GetHttpProxyClient(mgr manager.Manager) func(hostIp, podNamespace, podName string, port int) RayHttpProxyClientInterface
 }
 
 func ManagedByExternalController(controllerName *string) *string {
@@ -671,6 +685,115 @@ func GetRayClusterNameFromService(svc *corev1.Service) string {
 	return svc.Spec.Selector[RayClusterLabelKey]
 }
 
+// IsGatewayReady checks if a Gateway is considered "ready".
+//
+// A Gateway is "ready" only if both the `Accepted` and `Programmed` conditions
+// are set to 'True'.
+//
+//  1. 'Accepted': Signifies that the Gateway controller understands and accepts
+//     the Gateway resource. If 'False', it often indicates a conflict or an invalid
+//     specification.
+//
+//  2. 'Programmed': Signifies that the underlying network infrastructure for the Gateway
+//     (e.g. load balancer) has been successfully provisioned and configured.
+func IsGatewayReady(gatewayInstance *gwv1.Gateway) bool {
+	if gatewayInstance == nil {
+		return false
+	}
+
+	hasAccepted := meta.IsStatusConditionTrue(gatewayInstance.Status.Conditions, string(gwv1.GatewayConditionAccepted))
+	hasProgrammed := meta.IsStatusConditionTrue(gatewayInstance.Status.Conditions, string(gwv1.GatewayConditionProgrammed))
+
+	return hasAccepted && hasProgrammed
+}
+
+// IsHTTPRouteReady checks if an HTTPRoute is considered ready for a given Gateway.
+//
+// It returns true only if the route's parent status entry matching the Gateway has both
+// the 'Accepted' and 'ResolvedRefs' conditions set to 'True'.
+//
+//  1. 'Accepted': Signifies that the Gateway controller has validated the HTTPRoute's
+//     configuration (e.g. syntax, filters, matching rules). An 'Accepted' status of
+//     'False' means the route's specification is invalid.
+//
+//  2. 'ResolvedRefs': Signifies that all references within the route are valid, exist,
+//     and are resolvable by the Gateway.
+func IsHTTPRouteReady(gatewayInstance *gwv1.Gateway, httpRouteInstance *gwv1.HTTPRoute) bool {
+	if httpRouteInstance == nil {
+		return false
+	}
+	for _, parent := range httpRouteInstance.Status.Parents {
+		if parent.ParentRef.Name != gwv1.ObjectName(gatewayInstance.Name) {
+			continue
+		}
+		if parent.ParentRef.Namespace != nil && *parent.ParentRef.Namespace != gwv1.Namespace(gatewayInstance.Namespace) {
+			continue
+		}
+		hasAccepted := meta.IsStatusConditionTrue(parent.Conditions, string(gwv1.RouteConditionAccepted))
+		hasResolved := meta.IsStatusConditionTrue(parent.Conditions, string(gwv1.RouteConditionResolvedRefs))
+
+		if hasAccepted && hasResolved {
+			return true
+		}
+	}
+	return false
+}
+
+func IsIncrementalUpgradeEnabled(spec *rayv1.RayServiceSpec) bool {
+	if !features.Enabled(features.RayServiceIncrementalUpgrade) {
+		return false
+	}
+	return spec != nil && spec.UpgradeStrategy != nil &&
+		*spec.UpgradeStrategy.Type == rayv1.NewClusterWithIncrementalUpgrade
+}
+
+func GetRayServiceClusterUpgradeOptions(spec *rayv1.RayServiceSpec) *rayv1.ClusterUpgradeOptions {
+	if spec != nil && spec.UpgradeStrategy != nil {
+		return spec.UpgradeStrategy.ClusterUpgradeOptions
+	}
+	return nil
+}
+
+// IsIncrementalUpgradeComplete checks if the conditions for completing an incremental upgrade are met.
+func IsIncrementalUpgradeComplete(rayServiceInstance *rayv1.RayService, pendingCluster *rayv1.RayCluster) bool {
+	return pendingCluster != nil &&
+		ptr.Deref(rayServiceInstance.Status.ActiveServiceStatus.TargetCapacity, -1) == 0 &&
+		ptr.Deref(rayServiceInstance.Status.PendingServiceStatus.TrafficRoutedPercent, -1) == 100
+}
+
+// GetWeightsFromHTTPRoute parses a given HTTPRoute object and extracts the traffic weights
+// for the active and pending clusters (if present) of a RayService.
+func GetWeightsFromHTTPRoute(httpRoute *gwv1.HTTPRoute, rayServiceInstance *rayv1.RayService) (activeWeight int32, pendingWeight int32) {
+	var activeClusterName, pendingClusterName string
+	if rayServiceInstance != nil {
+		activeClusterName = rayServiceInstance.Status.ActiveServiceStatus.RayClusterName
+		pendingClusterName = rayServiceInstance.Status.PendingServiceStatus.RayClusterName
+	}
+
+	// Defaults if weights can't be detected. This is so that we avoid setting TrafficRoutedPercent
+	// before the HTTPRoute actually exists.
+	activeWeight = -1
+	pendingWeight = -1
+
+	if httpRoute == nil || len(httpRoute.Spec.Rules) == 0 || len(httpRoute.Spec.Rules[0].BackendRefs) == 0 {
+		return
+	}
+
+	for _, backendRef := range httpRoute.Spec.Rules[0].BackendRefs {
+		backendName := string(backendRef.Name)
+		weight := ptr.Deref(backendRef.Weight, 0)
+
+		if activeClusterName != "" && strings.Contains(backendName, activeClusterName) {
+			activeWeight = weight
+		}
+		if pendingClusterName != "" && strings.Contains(backendName, pendingClusterName) {
+			pendingWeight = weight
+		}
+	}
+
+	return
+}
+
 // Check where we are running. We are trying to distinguish here whether
 // this is vanilla kubernetes cluster or Openshift
 func GetClusterType() bool {
@@ -712,3 +835,93 @@ func GetContainerCommand(additionalOptions []string) []string {
 	bashOptionsStr := strings.Join(bashOptions, "")
 	return []string{"/bin/bash", "-" + bashOptionsStr, "--"}
 }
+
+// GetEnableDeterministicHeadName returns true if deterministic head pod name is enabled.
+func IsDeterministicHeadPodNameEnabled() bool {
+	return strings.ToLower(os.Getenv(ENABLE_DETERMINISTIC_HEAD_POD_NAME)) == "true"
+}
+
+// FetchHeadServiceURL fetches the URL that consists of the FQDN for the RayCluster's head service
+// and the port with the given port name (defaultPortName).
+func FetchHeadServiceURL(ctx context.Context, cli client.Client, rayCluster *rayv1.RayCluster, defaultPortName string) (string, error) {
+	headSvc := &corev1.Service{}
+	headSvcName, err := GenerateHeadServiceName(RayClusterCRD, rayCluster.Spec, rayCluster.Name)
+	if err != nil {
+		return "", err
+	}
+
+	if err = cli.Get(ctx, client.ObjectKey{Name: headSvcName, Namespace: rayCluster.Namespace}, headSvc); err != nil {
+		return "", err
+	}
+
+	servicePorts := headSvc.Spec.Ports
+	port := int32(-1)
+
+	for _, servicePort := range servicePorts {
+		if servicePort.Name == defaultPortName {
+			port = servicePort.Port
+			break
+		}
+	}
+
+	if port == int32(-1) {
+		return "", fmt.Errorf("%s port is not found", defaultPortName)
+	}
+
+	domainName := GetClusterDomainName()
+	headServiceURL := fmt.Sprintf("%s.%s.svc.%s:%v",
+		headSvc.Name,
+		headSvc.Namespace,
+		domainName,
+		port)
+	return headServiceURL, nil
+}
+
+func GetRayDashboardClientFunc(mgr manager.Manager, useKubernetesProxy bool) func(rayCluster *rayv1.RayCluster, url string) (dashboardclient.RayDashboardClientInterface, error) {
+	return func(rayCluster *rayv1.RayCluster, url string) (dashboardclient.RayDashboardClientInterface, error) {
+		dashboardClient := &dashboardclient.RayDashboardClient{}
+		if useKubernetesProxy {
+			var err error
+			headSvcName := rayCluster.Status.Head.ServiceName
+			if headSvcName == "" {
+				headSvcName, err = GenerateHeadServiceName(RayClusterCRD, rayCluster.Spec, rayCluster.Name)
+				if err != nil {
+					err = fmt.Errorf("failed to construct Ray dashboard client: %w", err)
+					return nil, err
+				}
+			}
+
+			dashboardClient.InitClient(
+				// Use `mgr.GetHTTPClient()` instead of `http.Client{}` so that the client has proper authentication
+				// configured to communicate with the Kubernetes API server.
+				mgr.GetHTTPClient(),
+				fmt.Sprintf("%s/api/v1/namespaces/%s/services/%s:dashboard/proxy", mgr.GetConfig().Host, rayCluster.Namespace, headSvcName),
+			)
+			return dashboardClient, nil
+		}
+
+		dashboardClient.InitClient(&http.Client{
+			Timeout: 2 * time.Second,
+		}, "http://"+url)
+		return dashboardClient, nil
+	}
+}
+
+func GetRayHttpProxyClientFunc(mgr manager.Manager, useKubernetesProxy bool) func(hostIp, podNamespace, podName string, port int) RayHttpProxyClientInterface {
+	return func(hostIp, podNamespace, podName string, port int) RayHttpProxyClientInterface {
+		if useKubernetesProxy {
+			return &RayHttpProxyClient{
+				client:       mgr.GetHTTPClient(),
+				httpProxyURL: fmt.Sprintf("%s/api/v1/namespaces/%s/pods/%s:%d/proxy/", mgr.GetConfig().Host, podNamespace, podName, port),
+			}
+		}
+		return &RayHttpProxyClient{
+			client:       &http.Client{Timeout: 2 * time.Second},
+			httpProxyURL: fmt.Sprintf("http://%s:%d/", hostIp, port),
+		}
+	}
+}
+
+func HasSubmitter(rayJobInstance *rayv1.RayJob) bool {
+	return rayJobInstance.Spec.SubmissionMode == rayv1.K8sJobMode || rayJobInstance.Spec.SubmissionMode == rayv1.SidecarMode
+}
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/validation.go b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/validation.go
index 6f5ce7a86..c7ff5ec78 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/validation.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/validation.go
@@ -3,6 +3,9 @@ package utils
 import (
 	errstd "errors"
 	"fmt"
+	"strconv"
+	"strings"
+	"time"
 
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/meta"
@@ -10,6 +13,7 @@ import (
 	"k8s.io/apimachinery/pkg/util/validation"
 
 	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
+	"github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboardclient"
 	"github.com/ray-project/kuberay/ray-operator/pkg/features"
 )
 
@@ -32,16 +36,73 @@ func ValidateRayClusterMetadata(metadata metav1.ObjectMeta) error {
 	return nil
 }
 
+// validateRayGroupResources checks for conflicting resource definitions.
+func validateRayGroupResources(groupName string, rayStartParams, resources map[string]string) error {
+	hasRayStartResources := rayStartParams["num-cpus"] != "" ||
+		rayStartParams["num-gpus"] != "" ||
+		rayStartParams["memory"] != "" ||
+		rayStartParams["resources"] != ""
+	if hasRayStartResources && len(resources) > 0 {
+		return fmt.Errorf("resource fields should not be set in both rayStartParams and Resources for %s group; please use only one", groupName)
+	}
+	return nil
+}
+
+// validateRayGroupLabels checks for invalid label definitions and correct label syntax.
+func validateRayGroupLabels(groupName string, rayStartParams, labels map[string]string) error {
+	if _, ok := rayStartParams["labels"]; ok {
+		return fmt.Errorf("rayStartParams['labels'] is not supported for %s group; please use the top-level Labels field instead", groupName)
+	}
+
+	// Validate that labels conforms to Kubernetes label syntax.
+	var allErrs []string
+	for key, val := range labels {
+		// Validate the label key.
+		if errs := validation.IsQualifiedName(key); len(errs) > 0 {
+			for _, err := range errs {
+				allErrs = append(allErrs, fmt.Sprintf("invalid label key for %s group: '%s', error: %s", groupName, key, err))
+			}
+		}
+
+		// Validate the label value.
+		if errs := validation.IsValidLabelValue(val); len(errs) > 0 {
+			for _, err := range errs {
+				allErrs = append(allErrs, fmt.Sprintf("invalid label value for key '%s' in %s group: '%s', error: %s", key, groupName, val, err))
+			}
+		}
+	}
+
+	if len(allErrs) > 0 {
+		return fmt.Errorf("%s", strings.Join(allErrs, "; "))
+	}
+
+	return nil
+}
+
 // Validation for invalid Ray Cluster configurations.
 func ValidateRayClusterSpec(spec *rayv1.RayClusterSpec, annotations map[string]string) error {
 	if len(spec.HeadGroupSpec.Template.Spec.Containers) == 0 {
 		return fmt.Errorf("headGroupSpec should have at least one container")
 	}
 
+	if err := validateRayGroupResources("Head", spec.HeadGroupSpec.RayStartParams, spec.HeadGroupSpec.Resources); err != nil {
+		return err
+	}
+	if err := validateRayGroupLabels("Head", spec.HeadGroupSpec.RayStartParams, spec.HeadGroupSpec.Labels); err != nil {
+		return err
+	}
+
 	for _, workerGroup := range spec.WorkerGroupSpecs {
 		if len(workerGroup.Template.Spec.Containers) == 0 {
 			return fmt.Errorf("workerGroupSpec should have at least one container")
 		}
+
+		if err := validateRayGroupResources(workerGroup.GroupName, workerGroup.RayStartParams, workerGroup.Resources); err != nil {
+			return err
+		}
+		if err := validateRayGroupLabels(workerGroup.GroupName, workerGroup.RayStartParams, workerGroup.Labels); err != nil {
+			return err
+		}
 	}
 
 	if annotations[RayFTEnabledAnnotationKey] != "" && spec.GcsFaultToleranceOptions != nil {
@@ -92,7 +153,19 @@ func ValidateRayClusterSpec(spec *rayv1.RayClusterSpec, annotations map[string]s
 		}
 	}
 
-	if IsAutoscalingEnabled(spec) {
+	// Check if autoscaling is enabled once to avoid repeated calls
+	isAutoscalingEnabled := IsAutoscalingEnabled(spec)
+
+	// Validate that RAY_enable_autoscaler_v2 environment variable is not set to "1" or "true" when autoscaler is disabled
+	if !isAutoscalingEnabled {
+		if envVar, exists := EnvVarByName(RAY_ENABLE_AUTOSCALER_V2, spec.HeadGroupSpec.Template.Spec.Containers[RayContainerIndex].Env); exists {
+			if envVar.Value == "1" || envVar.Value == "true" {
+				return fmt.Errorf("environment variable %s cannot be set to '%s' when enableInTreeAutoscaling is false. Please set enableInTreeAutoscaling: true to use autoscaler v2", RAY_ENABLE_AUTOSCALER_V2, envVar.Value)
+			}
+		}
+	}
+
+	if isAutoscalingEnabled {
 		for _, workerGroup := range spec.WorkerGroupSpecs {
 			if workerGroup.Suspend != nil && *workerGroup.Suspend {
 				// TODO (rueian): This can be supported in future Ray. We should check the RayVersion once we know the version.
@@ -121,17 +194,17 @@ func ValidateRayClusterSpec(spec *rayv1.RayClusterSpec, annotations map[string]s
 
 func ValidateRayJobStatus(rayJob *rayv1.RayJob) error {
 	if rayJob.Status.JobDeploymentStatus == rayv1.JobDeploymentStatusWaiting && rayJob.Spec.SubmissionMode != rayv1.InteractiveMode {
-		return fmt.Errorf("invalid RayJob State: JobDeploymentStatus cannot be `Waiting` when SubmissionMode is not InteractiveMode")
+		return fmt.Errorf("The RayJob status is invalid: JobDeploymentStatus cannot be `Waiting` when SubmissionMode is not InteractiveMode")
 	}
 	return nil
 }
 
 func ValidateRayJobMetadata(metadata metav1.ObjectMeta) error {
 	if len(metadata.Name) > MaxRayJobNameLength {
-		return fmt.Errorf("RayJob name should be no more than %d characters", MaxRayJobNameLength)
+		return fmt.Errorf("The RayJob metadata is invalid: RayJob name should be no more than %d characters", MaxRayJobNameLength)
 	}
 	if errs := validation.IsDNS1035Label(metadata.Name); len(errs) > 0 {
-		return fmt.Errorf("RayJob name should be a valid DNS1035 label: %v", errs)
+		return fmt.Errorf("The RayJob metadata is invalid: RayJob name should be a valid DNS1035 label: %v", errs)
 	}
 	return nil
 }
@@ -141,24 +214,35 @@ func ValidateRayJobSpec(rayJob *rayv1.RayJob) error {
 	// Kueue (https://kueue.sigs.k8s.io/docs/tasks/run_rayjobs/#c-limitations). For example, KubeRay allows users
 	// to suspend a RayJob with autoscaling enabled, but Kueue doesn't.
 	if rayJob.Spec.Suspend && !rayJob.Spec.ShutdownAfterJobFinishes {
-		return fmt.Errorf("a RayJob with shutdownAfterJobFinishes set to false is not allowed to be suspended")
+		return fmt.Errorf("The RayJob spec is invalid: a RayJob with shutdownAfterJobFinishes set to false is not allowed to be suspended")
 	}
 
 	if rayJob.Spec.TTLSecondsAfterFinished < 0 {
-		return fmt.Errorf("TTLSecondsAfterFinished must be a non-negative integer")
+		return fmt.Errorf("The RayJob spec is invalid: TTLSecondsAfterFinished must be a non-negative integer")
 	}
 
-	if !rayJob.Spec.ShutdownAfterJobFinishes && rayJob.Spec.TTLSecondsAfterFinished > 0 {
-		return fmt.Errorf("a RayJob with shutdownAfterJobFinishes set to false cannot have TTLSecondsAfterFinished")
+	// Validate TTL and deletion strategy together
+	if err := validateDeletionConfiguration(rayJob); err != nil {
+		return err
 	}
 
 	isClusterSelectorMode := len(rayJob.Spec.ClusterSelector) != 0
 	if rayJob.Spec.Suspend && isClusterSelectorMode {
-		return fmt.Errorf("the ClusterSelector mode doesn't support the suspend operation")
+		return fmt.Errorf("The RayJob spec is invalid: the ClusterSelector mode doesn't support the suspend operation")
 	}
 	if rayJob.Spec.RayClusterSpec == nil && !isClusterSelectorMode {
-		return fmt.Errorf("one of RayClusterSpec or ClusterSelector must be set")
+		return fmt.Errorf("The RayJob spec is invalid: one of RayClusterSpec or ClusterSelector must be set")
+	}
+	if isClusterSelectorMode {
+		clusterName := rayJob.Spec.ClusterSelector[RayJobClusterSelectorKey]
+		if len(clusterName) == 0 {
+			return fmt.Errorf("cluster name in ClusterSelector should not be empty")
+		}
+		if rayJob.Spec.SubmissionMode == rayv1.SidecarMode {
+			return fmt.Errorf("ClusterSelector is not supported in SidecarMode")
+		}
 	}
+
 	// InteractiveMode does not support backoffLimit > 1.
 	// When a RayJob fails (e.g., due to a missing script) and retries,
 	// spec.JobId remains set, causing the new job to incorrectly transition
@@ -167,50 +251,41 @@ func ValidateRayJobSpec(rayJob *rayv1.RayJob) error {
 	// to avoid ambiguous state handling and unintended behavior.
 	// https://github.com/ray-project/kuberay/issues/3525
 	if rayJob.Spec.SubmissionMode == rayv1.InteractiveMode && rayJob.Spec.BackoffLimit != nil && *rayJob.Spec.BackoffLimit > 0 {
-		return fmt.Errorf("BackoffLimit is incompatible with InteractiveMode")
+		return fmt.Errorf("The RayJob spec is invalid: BackoffLimit is incompatible with InteractiveMode")
+	}
+
+	if rayJob.Spec.SubmissionMode == rayv1.SidecarMode {
+		if rayJob.Spec.SubmitterPodTemplate != nil {
+			return fmt.Errorf("Currently, SidecarMode doesn't support SubmitterPodTemplate")
+		}
+
+		if rayJob.Spec.SubmitterConfig != nil {
+			return fmt.Errorf("Currently, SidecarMode doesn't support SubmitterConfig")
+		}
+
+		if rayJob.Spec.RayClusterSpec.HeadGroupSpec.Template.Spec.RestartPolicy != "" && rayJob.Spec.RayClusterSpec.HeadGroupSpec.Template.Spec.RestartPolicy != corev1.RestartPolicyNever {
+			return fmt.Errorf("restartPolicy for head Pod should be Never or unset when using SidecarMode")
+		}
 	}
 
 	if rayJob.Spec.RayClusterSpec != nil {
 		if err := ValidateRayClusterSpec(rayJob.Spec.RayClusterSpec, rayJob.Annotations); err != nil {
-			return err
+			return fmt.Errorf("The RayJob spec is invalid: %w", err)
 		}
 	}
 
 	// Validate whether RuntimeEnvYAML is a valid YAML string. Note that this only checks its validity
 	// as a YAML string, not its adherence to the runtime environment schema.
-	if _, err := UnmarshalRuntimeEnvYAML(rayJob.Spec.RuntimeEnvYAML); err != nil {
+	if _, err := dashboardclient.UnmarshalRuntimeEnvYAML(rayJob.Spec.RuntimeEnvYAML); err != nil {
 		return err
 	}
 	if rayJob.Spec.ActiveDeadlineSeconds != nil && *rayJob.Spec.ActiveDeadlineSeconds <= 0 {
-		return fmt.Errorf("activeDeadlineSeconds must be a positive integer")
+		return fmt.Errorf("The RayJob spec is invalid: activeDeadlineSeconds must be a positive integer")
 	}
 	if rayJob.Spec.BackoffLimit != nil && *rayJob.Spec.BackoffLimit < 0 {
-		return fmt.Errorf("backoffLimit must be a positive integer")
-	}
-	if !features.Enabled(features.RayJobDeletionPolicy) && rayJob.Spec.DeletionPolicy != nil {
-		return fmt.Errorf("RayJobDeletionPolicy feature gate must be enabled to use the DeletionPolicy feature")
+		return fmt.Errorf("The RayJob spec is invalid: backoffLimit must be a positive integer")
 	}
 
-	if rayJob.Spec.DeletionPolicy != nil {
-		policy := *rayJob.Spec.DeletionPolicy
-		if isClusterSelectorMode {
-			switch policy {
-			case rayv1.DeleteClusterDeletionPolicy:
-				return fmt.Errorf("the ClusterSelector mode doesn't support DeletionPolicy=DeleteCluster")
-			case rayv1.DeleteWorkersDeletionPolicy:
-				return fmt.Errorf("the ClusterSelector mode doesn't support DeletionPolicy=DeleteWorkers")
-			}
-		}
-
-		if policy == rayv1.DeleteWorkersDeletionPolicy && IsAutoscalingEnabled(rayJob.Spec.RayClusterSpec) {
-			// TODO (rueian): This can be supported in a future Ray version. We should check the RayVersion once we know it.
-			return fmt.Errorf("DeletionPolicy=DeleteWorkers currently does not support RayCluster with autoscaling enabled")
-		}
-
-		if rayJob.Spec.ShutdownAfterJobFinishes && policy == rayv1.DeleteNoneDeletionPolicy {
-			return fmt.Errorf("shutdownAfterJobFinshes is set to 'true' while deletion policy is 'DeleteNone'")
-		}
-	}
 	return nil
 }
 
@@ -221,9 +296,47 @@ func ValidateRayServiceMetadata(metadata metav1.ObjectMeta) error {
 	if errs := validation.IsDNS1035Label(metadata.Name); len(errs) > 0 {
 		return fmt.Errorf("RayService name should be a valid DNS1035 label: %v", errs)
 	}
+
+	// Validate initializing timeout annotation if present
+	if err := validateInitializingTimeout(metadata.Annotations); err != nil {
+		return fmt.Errorf("RayService annotations is invalid: %w", err)
+	}
+
 	return nil
 }
 
+// validateInitializingTimeout validates the ray.io/initializing-timeout annotation if present.
+// Accepts Go duration format (e.g., "5m", "1h") or integer seconds.
+// Returns an error if the annotation is present but invalid.
+func validateInitializingTimeout(annotations map[string]string) error {
+	if annotations == nil {
+		return nil
+	}
+
+	timeoutStr, exists := annotations[RayServiceInitializingTimeoutAnnotation]
+	if !exists || timeoutStr == "" {
+		return nil
+	}
+
+	// Try parsing as Go duration first (e.g., "30m", "1h")
+	if timeout, err := time.ParseDuration(timeoutStr); err == nil {
+		if timeout <= 0 {
+			return fmt.Errorf("annotation %s must be a positive duration, got: %s", RayServiceInitializingTimeoutAnnotation, timeoutStr)
+		}
+		return nil
+	}
+
+	// Try parsing as integer seconds
+	if seconds, err := strconv.Atoi(timeoutStr); err == nil {
+		if seconds <= 0 {
+			return fmt.Errorf("annotation %s must be a positive integer (seconds), got: %s", RayServiceInitializingTimeoutAnnotation, timeoutStr)
+		}
+		return nil
+	}
+
+	return fmt.Errorf("annotation %s has invalid format: %s. Expected Go duration format (e.g., '5m', '1h') or positive integer seconds", RayServiceInitializingTimeoutAnnotation, timeoutStr)
+}
+
 func ValidateRayServiceSpec(rayService *rayv1.RayService) error {
 	if err := ValidateRayClusterSpec(&rayService.Spec.RayClusterSpec, rayService.Annotations); err != nil {
 		return err
@@ -233,12 +346,231 @@ func ValidateRayServiceSpec(rayService *rayv1.RayService) error {
 		return fmt.Errorf("spec.rayClusterConfig.headGroupSpec.headService.metadata.name should not be set")
 	}
 
-	// only NewCluster and None are valid upgradeType
+	// only NewClusterWithIncrementalUpgrade, NewCluster, and None are valid upgradeType
 	if rayService.Spec.UpgradeStrategy != nil &&
 		rayService.Spec.UpgradeStrategy.Type != nil &&
 		*rayService.Spec.UpgradeStrategy.Type != rayv1.None &&
-		*rayService.Spec.UpgradeStrategy.Type != rayv1.NewCluster {
-		return fmt.Errorf("Spec.UpgradeStrategy.Type value %s is invalid, valid options are %s or %s", *rayService.Spec.UpgradeStrategy.Type, rayv1.NewCluster, rayv1.None)
+		*rayService.Spec.UpgradeStrategy.Type != rayv1.NewCluster &&
+		*rayService.Spec.UpgradeStrategy.Type != rayv1.NewClusterWithIncrementalUpgrade {
+		return fmt.Errorf("Spec.UpgradeStrategy.Type value %s is invalid, valid options are %s, %s, or %s", *rayService.Spec.UpgradeStrategy.Type, rayv1.NewClusterWithIncrementalUpgrade, rayv1.NewCluster, rayv1.None)
+	}
+
+	if rayService.Spec.RayClusterDeletionDelaySeconds != nil &&
+		*rayService.Spec.RayClusterDeletionDelaySeconds < 0 {
+		return fmt.Errorf("Spec.RayClusterDeletionDelaySeconds should be a non-negative integer, got %d", *rayService.Spec.RayClusterDeletionDelaySeconds)
+	}
+
+	// If type is NewClusterWithIncrementalUpgrade, validate the ClusterUpgradeOptions
+	if IsIncrementalUpgradeEnabled(&rayService.Spec) {
+		return ValidateClusterUpgradeOptions(rayService)
+	}
+
+	return nil
+}
+
+func ValidateClusterUpgradeOptions(rayService *rayv1.RayService) error {
+	if !IsAutoscalingEnabled(&rayService.Spec.RayClusterSpec) {
+		return fmt.Errorf("Ray Autoscaler is required for NewClusterWithIncrementalUpgrade")
+	}
+
+	options := rayService.Spec.UpgradeStrategy.ClusterUpgradeOptions
+	if options == nil {
+		return fmt.Errorf("ClusterUpgradeOptions are required for NewClusterWithIncrementalUpgrade")
 	}
+
+	// MaxSurgePercent defaults to 100% if unset.
+	if *options.MaxSurgePercent < 0 || *options.MaxSurgePercent > 100 {
+		return fmt.Errorf("maxSurgePercent must be between 0 and 100")
+	}
+
+	if options.StepSizePercent == nil || *options.StepSizePercent < 0 || *options.StepSizePercent > 100 {
+		return fmt.Errorf("stepSizePercent must be between 0 and 100")
+	}
+
+	if options.IntervalSeconds == nil || *options.IntervalSeconds <= 0 {
+		return fmt.Errorf("intervalSeconds must be greater than 0")
+	}
+
+	if options.GatewayClassName == "" {
+		return fmt.Errorf("gatewayClassName is required for NewClusterWithIncrementalUpgrade")
+	}
+
+	return nil
+}
+
+// validateDeletionConfiguration validates both deletion strategy and TTL configuration
+func validateDeletionConfiguration(rayJob *rayv1.RayJob) error {
+	if !rayJob.Spec.ShutdownAfterJobFinishes && rayJob.Spec.TTLSecondsAfterFinished > 0 {
+		return fmt.Errorf("The RayJob spec is invalid: a RayJob with shutdownAfterJobFinishes set to false cannot have TTLSecondsAfterFinished")
+	}
+
+	// No strategy block: nothing else to validate.
+	if rayJob.Spec.DeletionStrategy == nil {
+		return nil
+	}
+
+	// Feature gate must be enabled for any strategy usage.
+	if !features.Enabled(features.RayJobDeletionPolicy) {
+		return fmt.Errorf("RayJobDeletionPolicy feature gate must be enabled to use DeletionStrategy")
+	}
+
+	legacyConfigured := rayJob.Spec.DeletionStrategy.OnSuccess != nil || rayJob.Spec.DeletionStrategy.OnFailure != nil
+	rulesConfigured := len(rayJob.Spec.DeletionStrategy.DeletionRules) > 0
+
+	// Mutual exclusivity: rules mode forbids shutdown & legacy. (TTL+rules is implicitly invalid because TTL requires shutdown.)
+	if rulesConfigured && rayJob.Spec.ShutdownAfterJobFinishes {
+		return fmt.Errorf("The RayJob spec is invalid: spec.shutdownAfterJobFinishes and spec.deletionStrategy.deletionRules are mutually exclusive")
+	}
+	if rulesConfigured && legacyConfigured {
+		return fmt.Errorf("The RayJob spec is invalid: Cannot use both legacy onSuccess/onFailure fields and deletionRules simultaneously")
+	}
+
+	// Detailed content validation
+	if legacyConfigured {
+		if err := validateLegacyDeletionPolicies(rayJob); err != nil {
+			return err
+		}
+	} else if rulesConfigured {
+		if err := validateDeletionRules(rayJob); err != nil {
+			return err
+		}
+	} else {
+		return fmt.Errorf("The RayJob spec is invalid: DeletionStrategy requires either BOTH onSuccess and onFailure, OR the deletionRules field (cannot be empty)")
+	}
+
+	return nil
+}
+
+// validateDeletionRules validates the deletion rules in the RayJob spec.
+// It performs per-rule validations, checks for uniqueness, and ensures logical TTL consistency.
+// Errors are collected and returned as a single aggregated error using errors.Join for better user feedback.
+func validateDeletionRules(rayJob *rayv1.RayJob) error {
+	rules := rayJob.Spec.DeletionStrategy.DeletionRules
+	isClusterSelectorMode := len(rayJob.Spec.ClusterSelector) != 0
+
+	// Group TTLs by JobStatus for cross-rule validation and uniqueness checking.
+	rulesByStatus := make(map[rayv1.JobStatus]map[rayv1.DeletionPolicyType]int32)
+	var errs []error
+
+	// Single pass: Validate each rule individually and group for later consistency checks.
+	for i, rule := range rules {
+		// Validate TTL is non-negative.
+		if rule.Condition.TTLSeconds < 0 {
+			errs = append(errs, fmt.Errorf("deletionRules[%d]: TTLSeconds must be non-negative", i))
+			continue
+		}
+
+		// Contextual validations based on spec.
+		if isClusterSelectorMode && (rule.Policy == rayv1.DeleteCluster || rule.Policy == rayv1.DeleteWorkers) {
+			errs = append(errs, fmt.Errorf("deletionRules[%d]: DeletionPolicyType '%s' not supported when ClusterSelector is set", i, rule.Policy))
+			continue
+		}
+		if IsAutoscalingEnabled(rayJob.Spec.RayClusterSpec) && rule.Policy == rayv1.DeleteWorkers {
+			// TODO (rueian): Support in future Ray versions by checking RayVersion.
+			errs = append(errs, fmt.Errorf("deletionRules[%d]: DeletionPolicyType 'DeleteWorkers' not supported with autoscaling enabled", i))
+			continue
+		}
+
+		// Group valid rule for consistency check.
+		policyTTLs, ok := rulesByStatus[rule.Condition.JobStatus]
+		if !ok {
+			policyTTLs = make(map[rayv1.DeletionPolicyType]int32)
+			rulesByStatus[rule.Condition.JobStatus] = policyTTLs
+		}
+
+		// Check for uniqueness of (JobStatus, DeletionPolicyType) pair.
+		if _, exists := policyTTLs[rule.Policy]; exists {
+			errs = append(errs, fmt.Errorf("deletionRules[%d]: duplicate rule for DeletionPolicyType '%s' and JobStatus '%s'", i, rule.Policy, rule.Condition.JobStatus))
+			continue
+		}
+
+		policyTTLs[rule.Policy] = rule.Condition.TTLSeconds
+	}
+
+	// Second pass: Validate TTL consistency per JobStatus.
+	for status, policyTTLs := range rulesByStatus {
+		if err := validateTTLConsistency(policyTTLs, status); err != nil {
+			errs = append(errs, err)
+		}
+	}
+
+	return errstd.Join(errs...)
+}
+
+// validateTTLConsistency ensures TTLs follow the deletion hierarchy: Workers <= Cluster <= Self.
+// (Lower TTL means deletes earlier.)
+func validateTTLConsistency(policyTTLs map[rayv1.DeletionPolicyType]int32, status rayv1.JobStatus) error {
+	// Define the required deletion order. TTLs must be non-decreasing along this sequence.
+	deletionOrder := []rayv1.DeletionPolicyType{
+		rayv1.DeleteWorkers,
+		rayv1.DeleteCluster,
+		rayv1.DeleteSelf,
+	}
+
+	var prevPolicy rayv1.DeletionPolicyType
+	var prevTTL int32
+	var hasPrev bool
+
+	var errs []error
+
+	for _, policy := range deletionOrder {
+		ttl, exists := policyTTLs[policy]
+		if !exists {
+			continue
+		}
+
+		if hasPrev && ttl < prevTTL {
+			errs = append(errs, fmt.Errorf(
+				"for JobStatus '%s': %s TTL (%d) must be >= %s TTL (%d)",
+				status, policy, ttl, prevPolicy, prevTTL,
+			))
+		}
+
+		prevPolicy = policy
+		prevTTL = ttl
+		hasPrev = true
+	}
+
+	return errstd.Join(errs...)
+}
+
+// validateLegacyDeletionPolicies handles validation for the old `onSuccess` and `onFailure` fields.
+func validateLegacyDeletionPolicies(rayJob *rayv1.RayJob) error {
+	isClusterSelectorMode := len(rayJob.Spec.ClusterSelector) != 0
+
+	// Both policies must be set if using the legacy API.
+	if rayJob.Spec.DeletionStrategy.OnSuccess == nil || rayJob.Spec.DeletionStrategy.OnFailure == nil {
+		return fmt.Errorf("both DeletionStrategy.OnSuccess and DeletionStrategy.OnFailure must be set when using the legacy deletion policy fields of DeletionStrategy")
+	}
+
+	// Validate that the Policy field is set within each policy.
+	onSuccessPolicy := rayJob.Spec.DeletionStrategy.OnSuccess
+	onFailurePolicy := rayJob.Spec.DeletionStrategy.OnFailure
+
+	if onSuccessPolicy.Policy == nil {
+		return fmt.Errorf("the DeletionPolicyType field of DeletionStrategy.OnSuccess cannot be unset when DeletionStrategy is enabled")
+	}
+	if onFailurePolicy.Policy == nil {
+		return fmt.Errorf("the DeletionPolicyType field of DeletionStrategy.OnFailure cannot be unset when DeletionStrategy is enabled")
+	}
+
+	if isClusterSelectorMode {
+		if *onSuccessPolicy.Policy == rayv1.DeleteCluster || *onSuccessPolicy.Policy == rayv1.DeleteWorkers {
+			return fmt.Errorf("the ClusterSelector mode doesn't support DeletionStrategy=%s on success", *onSuccessPolicy.Policy)
+		}
+		if *onFailurePolicy.Policy == rayv1.DeleteCluster || *onFailurePolicy.Policy == rayv1.DeleteWorkers {
+			return fmt.Errorf("the ClusterSelector mode doesn't support DeletionStrategy=%s on failure", *onFailurePolicy.Policy)
+		}
+	}
+
+	if (*onSuccessPolicy.Policy == rayv1.DeleteWorkers || *onFailurePolicy.Policy == rayv1.DeleteWorkers) && IsAutoscalingEnabled(rayJob.Spec.RayClusterSpec) {
+		// TODO (rueian): This can be supported in a future Ray version. We should check the RayVersion once we know it.
+		return fmt.Errorf("DeletionStrategy=DeleteWorkers currently does not support RayCluster with autoscaling enabled")
+	}
+
+	if rayJob.Spec.ShutdownAfterJobFinishes && (*onSuccessPolicy.Policy == rayv1.DeleteNone || *onFailurePolicy.Policy == rayv1.DeleteNone) {
+		return fmt.Errorf("The RayJob spec is invalid: shutdownAfterJobFinshes is set to 'true' while deletion policy is 'DeleteNone'")
+	}
+
 	return nil
 }
diff --git a/vendor/github.com/ray-project/kuberay/ray-operator/pkg/features/features.go b/vendor/github.com/ray-project/kuberay/ray-operator/pkg/features/features.go
index 2abea2ffb..16b23ab83 100644
--- a/vendor/github.com/ray-project/kuberay/ray-operator/pkg/features/features.go
+++ b/vendor/github.com/ray-project/kuberay/ray-operator/pkg/features/features.go
@@ -24,6 +24,19 @@ const (
 	//
 	// Enables new deletion policy API in RayJob
 	RayJobDeletionPolicy featuregate.Feature = "RayJobDeletionPolicy"
+
+	// owner: @aaronliang
+	// rep: N/A
+	// alpha: v1.0
+	// Enables multi-host worker indexing
+	RayMultiHostIndexing featuregate.Feature = "RayMultiHostIndexing"
+
+	// owner: @ryanaoleary
+	// rep: N/A
+	// alpha: v1.0
+	//
+	// Enabled NewClusterWithIncrementalUpgrade type for RayService zero-downtime upgrades.
+	RayServiceIncrementalUpgrade featuregate.Feature = "RayServiceIncrementalUpgrade"
 )
 
 func init() {
@@ -31,8 +44,10 @@ func init() {
 }
 
 var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
-	RayClusterStatusConditions: {Default: true, PreRelease: featuregate.Beta},
-	RayJobDeletionPolicy:       {Default: false, PreRelease: featuregate.Alpha},
+	RayClusterStatusConditions:   {Default: true, PreRelease: featuregate.Beta},
+	RayJobDeletionPolicy:         {Default: false, PreRelease: featuregate.Alpha},
+	RayMultiHostIndexing:         {Default: false, PreRelease: featuregate.Alpha},
+	RayServiceIncrementalUpgrade: {Default: false, PreRelease: featuregate.Alpha},
 }
 
 // SetFeatureGateDuringTest is a helper method to override feature gates in tests.
diff --git a/vendor/go.uber.org/automaxprocs/.codecov.yml b/vendor/go.uber.org/automaxprocs/.codecov.yml
deleted file mode 100644
index 9a2ed4a99..000000000
--- a/vendor/go.uber.org/automaxprocs/.codecov.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-coverage:
-  range: 80..100
-  round: down
-  precision: 2
-
-  status:
-    project:                   # measuring the overall project coverage
-      default:                 # context, you can create multiple ones with custom titles
-        enabled: yes           # must be yes|true to enable this status
-        target: 90%            # specify the target coverage for each commit status
-                               #   option: "auto" (must increase from parent commit or pull request base)
-                               #   option: "X%" a static target percentage to hit
-        if_not_found: success  # if parent is not found report status as success, error, or failure
-        if_ci_failed: error    # if ci fails report status as success, error, or failure
diff --git a/vendor/go.uber.org/automaxprocs/.gitignore b/vendor/go.uber.org/automaxprocs/.gitignore
deleted file mode 100644
index dd7bcf513..000000000
--- a/vendor/go.uber.org/automaxprocs/.gitignore
+++ /dev/null
@@ -1,33 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-vendor
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-*.prof
-*.pprof
-*.out
-*.log
-coverage.txt
-
-/bin
-cover.out
-cover.html
diff --git a/vendor/go.uber.org/automaxprocs/CHANGELOG.md b/vendor/go.uber.org/automaxprocs/CHANGELOG.md
deleted file mode 100644
index f421056ae..000000000
--- a/vendor/go.uber.org/automaxprocs/CHANGELOG.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# Changelog
-
-## v1.6.0 (2024-07-24)
-
-- Add RoundQuotaFunc option that allows configuration of rounding
-  behavior for floating point CPU quota.
-
-## v1.5.3 (2023-07-19)
-
-- Fix mountinfo parsing when super options have fields with spaces.
-- Fix division by zero while parsing cgroups.
-
-## v1.5.2 (2023-03-16)
-
-- Support child control cgroups
-- Fix file descriptor leak
-- Update dependencies
-
-## v1.5.1 (2022-04-06)
-
-- Fix cgroups v2 mountpoint detection.
-
-## v1.5.0 (2022-04-05)
-
-- Add support for cgroups v2.
-
-Thanks to @emadolsky for their contribution to this release.
-
-## v1.4.0 (2021-02-01)
-
-- Support colons in cgroup names.
-- Remove linters from runtime dependencies.
-
-## v1.3.0 (2020-01-23)
-
-- Migrate to Go modules.
-
-## v1.2.0 (2018-02-22)
-
-- Fixed quota clamping to always round down rather than up; Rather than
-  guaranteeing constant throttling at saturation, instead assume that the
-  fractional CPU was added as a hedge for factors outside of Go's scheduler.
-
-## v1.1.0 (2017-11-10)
-
-- Log the new value of `GOMAXPROCS` rather than the current value.
-- Make logs more explicit about whether `GOMAXPROCS` was modified or not.
-- Allow customization of the minimum `GOMAXPROCS`, and modify default from 2 to 1.
-
-## v1.0.0 (2017-08-09)
-
-- Initial release.
diff --git a/vendor/go.uber.org/automaxprocs/CODE_OF_CONDUCT.md b/vendor/go.uber.org/automaxprocs/CODE_OF_CONDUCT.md
deleted file mode 100644
index e327d9aa5..000000000
--- a/vendor/go.uber.org/automaxprocs/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1,75 +0,0 @@
-# Contributor Covenant Code of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as
-contributors and maintainers pledge to making participation in our project and
-our community a harassment-free experience for everyone, regardless of age,
-body size, disability, ethnicity, gender identity and expression, level of
-experience, nationality, personal appearance, race, religion, or sexual
-identity and orientation.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment
-include:
-
-* Using welcoming and inclusive language
-* Being respectful of differing viewpoints and experiences
-* Gracefully accepting constructive criticism
-* Focusing on what is best for the community
-* Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-* The use of sexualized language or imagery and unwelcome sexual attention or
-  advances
-* Trolling, insulting/derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or electronic
-  address, without explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
-  professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable
-behavior and are expected to take appropriate and fair corrective action in
-response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or
-reject comments, commits, code, wiki edits, issues, and other contributions
-that are not aligned to this Code of Conduct, or to ban temporarily or
-permanently any contributor for other behaviors that they deem inappropriate,
-threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces
-when an individual is representing the project or its community. Examples of
-representing a project or community include using an official project e-mail
-address, posting via an official social media account, or acting as an
-appointed representative at an online or offline event. Representation of a
-project may be further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be
-reported by contacting the project team at oss-conduct@uber.com. The project
-team will review and investigate all complaints, and will respond in a way
-that it deems appropriate to the circumstances. The project team is obligated
-to maintain confidentiality with regard to the reporter of an incident.
-Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good
-faith may face temporary or permanent repercussions as determined by other
-members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage],
-version 1.4, available at
-[http://contributor-covenant.org/version/1/4][version].
-
-[homepage]: http://contributor-covenant.org
-[version]: http://contributor-covenant.org/version/1/4/
diff --git a/vendor/go.uber.org/automaxprocs/CONTRIBUTING.md b/vendor/go.uber.org/automaxprocs/CONTRIBUTING.md
deleted file mode 100644
index 2b6a6040d..000000000
--- a/vendor/go.uber.org/automaxprocs/CONTRIBUTING.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Contributing
-
-We'd love your help improving this package!
-
-If you'd like to add new exported APIs, please [open an issue][open-issue]
-describing your proposal &mdash; discussing API changes ahead of time makes
-pull request review much smoother. In your issue, pull request, and any other
-communications, please remember to treat your fellow contributors with
-respect! We take our [code of conduct](CODE_OF_CONDUCT.md) seriously.
-
-Note that you'll need to sign [Uber's Contributor License Agreement][cla]
-before we can accept any of your contributions. If necessary, a bot will remind
-you to accept the CLA when you open your pull request.
-
-## Setup
-
-[Fork][fork], then clone the repository:
-
-```
-mkdir -p $GOPATH/src/go.uber.org
-cd $GOPATH/src/go.uber.org
-git clone git@github.com:your_github_username/automaxprocs.git
-cd automaxprocs
-git remote add upstream https://github.com/uber-go/automaxprocs.git
-git fetch upstream
-```
-
-Install the test dependencies:
-
-```
-make dependencies
-```
-
-Make sure that the tests and the linters pass:
-
-```
-make test
-make lint
-```
-
-If you're not using the minor version of Go specified in the Makefile's
-`LINTABLE_MINOR_VERSIONS` variable, `make lint` doesn't do anything. This is
-fine, but it means that you'll only discover lint failures after you open your
-pull request.
-
-## Making Changes
-
-Start by creating a new branch for your changes:
-
-```
-cd $GOPATH/src/go.uber.org/automaxprocs
-git checkout master
-git fetch upstream
-git rebase upstream/master
-git checkout -b cool_new_feature
-```
-
-Make your changes, then ensure that `make lint` and `make test` still pass. If
-you're satisfied with your changes, push them to your fork.
-
-```
-git push origin cool_new_feature
-```
-
-Then use the GitHub UI to open a pull request.
-
-At this point, you're waiting on us to review your changes. We *try* to respond
-to issues and pull requests within a few business days, and we may suggest some
-improvements or alternatives. Once your changes are approved, one of the
-project maintainers will merge them.
-
-We're much more likely to approve your changes if you:
-
-* Add tests for new functionality.
-* Write a [good commit message][commit-message].
-* Maintain backward compatibility.
-
-[fork]: https://github.com/uber-go/automaxprocs/fork
-[open-issue]: https://github.com/uber-go/automaxprocs/issues/new
-[cla]: https://cla-assistant.io/uber-go/automaxprocs
-[commit-message]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html
diff --git a/vendor/go.uber.org/automaxprocs/LICENSE b/vendor/go.uber.org/automaxprocs/LICENSE
deleted file mode 100644
index 20dcf51d9..000000000
--- a/vendor/go.uber.org/automaxprocs/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2017 Uber Technologies, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/vendor/go.uber.org/automaxprocs/Makefile b/vendor/go.uber.org/automaxprocs/Makefile
deleted file mode 100644
index 1642b7148..000000000
--- a/vendor/go.uber.org/automaxprocs/Makefile
+++ /dev/null
@@ -1,46 +0,0 @@
-export GOBIN ?= $(shell pwd)/bin
-
-GO_FILES := $(shell \
-	find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
-	-o -name '*.go' -print | cut -b3-)
-
-GOLINT = $(GOBIN)/golint
-STATICCHECK = $(GOBIN)/staticcheck
-
-.PHONY: build
-build:
-	go build ./...
-
-.PHONY: install
-install:
-	go mod download
-
-.PHONY: test
-test:
-	go test -race ./...
-
-.PHONY: cover
-cover:
-	go test -coverprofile=cover.out -covermode=atomic -coverpkg=./... ./...
-	go tool cover -html=cover.out -o cover.html
-
-$(GOLINT): tools/go.mod
-	cd tools && go install golang.org/x/lint/golint
-
-$(STATICCHECK): tools/go.mod
-	cd tools && go install honnef.co/go/tools/cmd/staticcheck@2023.1.2
-
-.PHONY: lint
-lint: $(GOLINT) $(STATICCHECK)
-	@rm -rf lint.log
-	@echo "Checking gofmt"
-	@gofmt -d -s $(GO_FILES) 2>&1 | tee lint.log
-	@echo "Checking go vet"
-	@go vet ./... 2>&1 | tee -a lint.log
-	@echo "Checking golint"
-	@$(GOLINT) ./... | tee -a lint.log
-	@echo "Checking staticcheck"
-	@$(STATICCHECK) ./... 2>&1 |  tee -a lint.log
-	@echo "Checking for license headers..."
-	@./.build/check_license.sh | tee -a lint.log
-	@[ ! -s lint.log ]
diff --git a/vendor/go.uber.org/automaxprocs/README.md b/vendor/go.uber.org/automaxprocs/README.md
deleted file mode 100644
index bfed32ada..000000000
--- a/vendor/go.uber.org/automaxprocs/README.md
+++ /dev/null
@@ -1,71 +0,0 @@
-# automaxprocs [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
-
-Automatically set `GOMAXPROCS` to match Linux container CPU quota.
-
-## Installation
-
-`go get -u go.uber.org/automaxprocs`
-
-## Quick Start
-
-```go
-import _ "go.uber.org/automaxprocs"
-
-func main() {
-  // Your application logic here.
-}
-```
-
-# Performance
-Data measured from Uber's internal load balancer. We ran the load balancer with 200% CPU quota (i.e., 2 cores):
-
-| GOMAXPROCS         |  RPS      | P50 (ms) | P99.9 (ms) |
-| ------------------ | --------- | -------- | ---------- |
-| 1                  | 28,893.18 | 1.46     | 19.70      |
-| 2 (equal to quota) | 44,715.07 | 0.84     | 26.38      |
-| 3                  | 44,212.93 | 0.66     | 30.07      |
-| 4                  | 41,071.15 | 0.57     | 42.94      |
-| 8                  | 33,111.69 | 0.43     | 64.32      |
-| Default (24)       | 22,191.40 | 0.45     | 76.19      |
-
-When `GOMAXPROCS` is increased above the CPU quota, we see P50 decrease slightly, but see significant increases to P99. We also see that the total RPS handled also decreases.
-
-When `GOMAXPROCS` is higher than the CPU quota allocated, we also saw significant throttling:
-
-```
-$ cat /sys/fs/cgroup/cpu,cpuacct/system.slice/[...]/cpu.stat
-nr_periods 42227334
-nr_throttled 131923
-throttled_time 88613212216618
-```
-
-Once `GOMAXPROCS` was reduced to match the CPU quota, we saw no CPU throttling.
-
-## Development Status: Stable
-
-All APIs are finalized, and no breaking changes will be made in the 1.x series
-of releases. Users of semver-aware dependency management systems should pin
-automaxprocs to `^1`.
-
-## Contributing
-
-We encourage and support an active, healthy community of contributors &mdash;
-including you! Details are in the [contribution guide](CONTRIBUTING.md) and
-the [code of conduct](CODE_OF_CONDUCT.md). The automaxprocs maintainers keep
-an eye on issues and pull requests, but you can also report any negative
-conduct to oss-conduct@uber.com. That email list is a private, safe space;
-even the automaxprocs maintainers don't have access, so don't hesitate to hold
-us to a high standard.
-
-<hr>
-
-Released under the [MIT License](LICENSE).
-
-[doc-img]: https://godoc.org/go.uber.org/automaxprocs?status.svg
-[doc]: https://godoc.org/go.uber.org/automaxprocs
-[ci-img]: https://github.com/uber-go/automaxprocs/actions/workflows/go.yml/badge.svg
-[ci]: https://github.com/uber-go/automaxprocs/actions/workflows/go.yml
-[cov-img]: https://codecov.io/gh/uber-go/automaxprocs/branch/master/graph/badge.svg
-[cov]: https://codecov.io/gh/uber-go/automaxprocs
-
-
diff --git a/vendor/go.uber.org/automaxprocs/automaxprocs.go b/vendor/go.uber.org/automaxprocs/automaxprocs.go
deleted file mode 100644
index 69946a3e1..000000000
--- a/vendor/go.uber.org/automaxprocs/automaxprocs.go
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Package automaxprocs automatically sets GOMAXPROCS to match the Linux
-// container CPU quota, if any.
-package automaxprocs // import "go.uber.org/automaxprocs"
-
-import (
-	"log"
-
-	"go.uber.org/automaxprocs/maxprocs"
-)
-
-func init() {
-	maxprocs.Set(maxprocs.Logger(log.Printf))
-}
diff --git a/vendor/go.uber.org/automaxprocs/internal/cgroups/doc.go b/vendor/go.uber.org/automaxprocs/internal/cgroups/doc.go
deleted file mode 100644
index 113555f63..000000000
--- a/vendor/go.uber.org/automaxprocs/internal/cgroups/doc.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Package cgroups provides utilities to access Linux control group (CGroups)
-// parameters (CPU quota, for example) for a given process.
-package cgroups
diff --git a/vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go b/vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go
deleted file mode 100644
index e561fe60b..000000000
--- a/vendor/go.uber.org/automaxprocs/maxprocs/maxprocs.go
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-// Package maxprocs lets Go programs easily configure runtime.GOMAXPROCS to
-// match the configured Linux CPU quota. Unlike the top-level automaxprocs
-// package, it lets the caller configure logging and handle errors.
-package maxprocs // import "go.uber.org/automaxprocs/maxprocs"
-
-import (
-	"os"
-	"runtime"
-
-	iruntime "go.uber.org/automaxprocs/internal/runtime"
-)
-
-const _maxProcsKey = "GOMAXPROCS"
-
-func currentMaxProcs() int {
-	return runtime.GOMAXPROCS(0)
-}
-
-type config struct {
-	printf         func(string, ...interface{})
-	procs          func(int, func(v float64) int) (int, iruntime.CPUQuotaStatus, error)
-	minGOMAXPROCS  int
-	roundQuotaFunc func(v float64) int
-}
-
-func (c *config) log(fmt string, args ...interface{}) {
-	if c.printf != nil {
-		c.printf(fmt, args...)
-	}
-}
-
-// An Option alters the behavior of Set.
-type Option interface {
-	apply(*config)
-}
-
-// Logger uses the supplied printf implementation for log output. By default,
-// Set doesn't log anything.
-func Logger(printf func(string, ...interface{})) Option {
-	return optionFunc(func(cfg *config) {
-		cfg.printf = printf
-	})
-}
-
-// Min sets the minimum GOMAXPROCS value that will be used.
-// Any value below 1 is ignored.
-func Min(n int) Option {
-	return optionFunc(func(cfg *config) {
-		if n >= 1 {
-			cfg.minGOMAXPROCS = n
-		}
-	})
-}
-
-// RoundQuotaFunc sets the function that will be used to covert the CPU quota from float to int.
-func RoundQuotaFunc(rf func(v float64) int) Option {
-	return optionFunc(func(cfg *config) {
-		cfg.roundQuotaFunc = rf
-	})
-}
-
-type optionFunc func(*config)
-
-func (of optionFunc) apply(cfg *config) { of(cfg) }
-
-// Set GOMAXPROCS to match the Linux container CPU quota (if any), returning
-// any error encountered and an undo function.
-//
-// Set is a no-op on non-Linux systems and in Linux environments without a
-// configured CPU quota.
-func Set(opts ...Option) (func(), error) {
-	cfg := &config{
-		procs:          iruntime.CPUQuotaToGOMAXPROCS,
-		roundQuotaFunc: iruntime.DefaultRoundFunc,
-		minGOMAXPROCS:  1,
-	}
-	for _, o := range opts {
-		o.apply(cfg)
-	}
-
-	undoNoop := func() {
-		cfg.log("maxprocs: No GOMAXPROCS change to reset")
-	}
-
-	// Honor the GOMAXPROCS environment variable if present. Otherwise, amend
-	// `runtime.GOMAXPROCS()` with the current process' CPU quota if the OS is
-	// Linux, and guarantee a minimum value of 1. The minimum guaranteed value
-	// can be overridden using `maxprocs.Min()`.
-	if max, exists := os.LookupEnv(_maxProcsKey); exists {
-		cfg.log("maxprocs: Honoring GOMAXPROCS=%q as set in environment", max)
-		return undoNoop, nil
-	}
-
-	maxProcs, status, err := cfg.procs(cfg.minGOMAXPROCS, cfg.roundQuotaFunc)
-	if err != nil {
-		return undoNoop, err
-	}
-
-	if status == iruntime.CPUQuotaUndefined {
-		cfg.log("maxprocs: Leaving GOMAXPROCS=%v: CPU quota undefined", currentMaxProcs())
-		return undoNoop, nil
-	}
-
-	prev := currentMaxProcs()
-	undo := func() {
-		cfg.log("maxprocs: Resetting GOMAXPROCS to %v", prev)
-		runtime.GOMAXPROCS(prev)
-	}
-
-	switch status {
-	case iruntime.CPUQuotaMinUsed:
-		cfg.log("maxprocs: Updating GOMAXPROCS=%v: using minimum allowed GOMAXPROCS", maxProcs)
-	case iruntime.CPUQuotaUsed:
-		cfg.log("maxprocs: Updating GOMAXPROCS=%v: determined from CPU quota", maxProcs)
-	}
-
-	runtime.GOMAXPROCS(maxProcs)
-	return undo, nil
-}
diff --git a/vendor/go.uber.org/automaxprocs/maxprocs/version.go b/vendor/go.uber.org/automaxprocs/maxprocs/version.go
deleted file mode 100644
index cc7fc5aee..000000000
--- a/vendor/go.uber.org/automaxprocs/maxprocs/version.go
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2017 Uber Technologies, Inc.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-
-package maxprocs
-
-// Version is the current package version.
-const Version = "1.6.0"
diff --git a/vendor/golang.org/x/crypto/curve25519/curve25519.go b/vendor/golang.org/x/crypto/curve25519/curve25519.go
index 8ff087df4..048faef3a 100644
--- a/vendor/golang.org/x/crypto/curve25519/curve25519.go
+++ b/vendor/golang.org/x/crypto/curve25519/curve25519.go
@@ -3,11 +3,14 @@
 // license that can be found in the LICENSE file.
 
 // Package curve25519 provides an implementation of the X25519 function, which
-// performs scalar multiplication on the elliptic curve known as Curve25519.
-// See RFC 7748.
+// performs scalar multiplication on the elliptic curve known as Curve25519
+// according to [RFC 7748].
 //
-// This package is a wrapper for the X25519 implementation
-// in the crypto/ecdh package.
+// The curve25519 package is a wrapper for the X25519 implementation in the
+// crypto/ecdh package. It is [frozen] and is not accepting new features.
+//
+// [RFC 7748]: https://datatracker.ietf.org/doc/html/rfc7748
+// [frozen]: https://go.dev/wiki/Frozen
 package curve25519
 
 import "crypto/ecdh"
diff --git a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
index 3685b3445..75df77406 100644
--- a/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
+++ b/vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go
@@ -3,6 +3,10 @@
 // license that can be found in the LICENSE file.
 
 // Package salsa provides low-level access to functions in the Salsa family.
+//
+// Deprecated: this package exposes unsafe low-level operations. New applications
+// should consider using the AEAD construction in golang.org/x/crypto/chacha20poly1305
+// instead. Existing users should migrate to golang.org/x/crypto/salsa20.
 package salsa
 
 import "math/bits"
diff --git a/vendor/golang.org/x/crypto/ssh/cipher.go b/vendor/golang.org/x/crypto/ssh/cipher.go
index 6a5b582aa..7554ed57a 100644
--- a/vendor/golang.org/x/crypto/ssh/cipher.go
+++ b/vendor/golang.org/x/crypto/ssh/cipher.go
@@ -8,6 +8,7 @@ import (
 	"crypto/aes"
 	"crypto/cipher"
 	"crypto/des"
+	"crypto/fips140"
 	"crypto/rc4"
 	"crypto/subtle"
 	"encoding/binary"
@@ -15,6 +16,7 @@ import (
 	"fmt"
 	"hash"
 	"io"
+	"slices"
 
 	"golang.org/x/crypto/chacha20"
 	"golang.org/x/crypto/internal/poly1305"
@@ -93,41 +95,41 @@ func streamCipherMode(skip int, createFunc func(key, iv []byte) (cipher.Stream,
 }
 
 // cipherModes documents properties of supported ciphers. Ciphers not included
-// are not supported and will not be negotiated, even if explicitly requested in
-// ClientConfig.Crypto.Ciphers.
-var cipherModes = map[string]*cipherMode{
-	// Ciphers from RFC 4344, which introduced many CTR-based ciphers. Algorithms
-	// are defined in the order specified in the RFC.
-	CipherAES128CTR: {16, aes.BlockSize, streamCipherMode(0, newAESCTR)},
-	CipherAES192CTR: {24, aes.BlockSize, streamCipherMode(0, newAESCTR)},
-	CipherAES256CTR: {32, aes.BlockSize, streamCipherMode(0, newAESCTR)},
-
-	// Ciphers from RFC 4345, which introduces security-improved arcfour ciphers.
-	// They are defined in the order specified in the RFC.
-	InsecureCipherRC4128: {16, 0, streamCipherMode(1536, newRC4)},
-	InsecureCipherRC4256: {32, 0, streamCipherMode(1536, newRC4)},
-
-	// Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
-	// Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
-	// RC4) has problems with weak keys, and should be used with caution."
-	// RFC 4345 introduces improved versions of Arcfour.
-	InsecureCipherRC4: {16, 0, streamCipherMode(0, newRC4)},
-
-	// AEAD ciphers
-	CipherAES128GCM:        {16, 12, newGCMCipher},
-	CipherAES256GCM:        {32, 12, newGCMCipher},
-	CipherChaCha20Poly1305: {64, 0, newChaCha20Cipher},
-
+// are not supported and will not be negotiated, even if explicitly configured.
+// When FIPS mode is enabled, only FIPS-approved algorithms are included.
+var cipherModes = map[string]*cipherMode{}
+
+func init() {
+	cipherModes[CipherAES128CTR] = &cipherMode{16, aes.BlockSize, streamCipherMode(0, newAESCTR)}
+	cipherModes[CipherAES192CTR] = &cipherMode{24, aes.BlockSize, streamCipherMode(0, newAESCTR)}
+	cipherModes[CipherAES256CTR] = &cipherMode{32, aes.BlockSize, streamCipherMode(0, newAESCTR)}
+	//  Use of GCM with arbitrary IVs is not allowed in FIPS 140-only mode,
+	// we'll wire it up to NewGCMForSSH in Go 1.26.
+	//
+	// For now it means we'll work with fips140=on but not fips140=only.
+	cipherModes[CipherAES128GCM] = &cipherMode{16, 12, newGCMCipher}
+	cipherModes[CipherAES256GCM] = &cipherMode{32, 12, newGCMCipher}
+
+	if fips140.Enabled() {
+		defaultCiphers = slices.DeleteFunc(defaultCiphers, func(algo string) bool {
+			_, ok := cipherModes[algo]
+			return !ok
+		})
+		return
+	}
+
+	cipherModes[CipherChaCha20Poly1305] = &cipherMode{64, 0, newChaCha20Cipher}
+	// Insecure ciphers not included in the default configuration.
+	cipherModes[InsecureCipherRC4128] = &cipherMode{16, 0, streamCipherMode(1536, newRC4)}
+	cipherModes[InsecureCipherRC4256] = &cipherMode{32, 0, streamCipherMode(1536, newRC4)}
+	cipherModes[InsecureCipherRC4] = &cipherMode{16, 0, streamCipherMode(0, newRC4)}
 	// CBC mode is insecure and so is not included in the default config.
 	// (See https://www.ieee-security.org/TC/SP2013/papers/4977a526.pdf). If absolutely
 	// needed, it's possible to specify a custom Config to enable it.
 	// You should expect that an active attacker can recover plaintext if
 	// you do.
-	InsecureCipherAES128CBC: {16, aes.BlockSize, newAESCBCCipher},
-
-	// 3des-cbc is insecure and is not included in the default
-	// config.
-	InsecureCipherTripleDESCBC: {24, des.BlockSize, newTripleDESCBCCipher},
+	cipherModes[InsecureCipherAES128CBC] = &cipherMode{16, aes.BlockSize, newAESCBCCipher}
+	cipherModes[InsecureCipherTripleDESCBC] = &cipherMode{24, des.BlockSize, newTripleDESCBCCipher}
 }
 
 // prefixLen is the length of the packet prefix that contains the packet length
diff --git a/vendor/golang.org/x/crypto/ssh/client_auth.go b/vendor/golang.org/x/crypto/ssh/client_auth.go
index c12818fdc..3127e4990 100644
--- a/vendor/golang.org/x/crypto/ssh/client_auth.go
+++ b/vendor/golang.org/x/crypto/ssh/client_auth.go
@@ -9,6 +9,7 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"slices"
 	"strings"
 )
 
@@ -83,7 +84,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
 			// success
 			return nil
 		} else if ok == authFailure {
-			if m := auth.method(); !contains(tried, m) {
+			if m := auth.method(); !slices.Contains(tried, m) {
 				tried = append(tried, m)
 			}
 		}
@@ -97,7 +98,7 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
 	findNext:
 		for _, a := range config.Auth {
 			candidateMethod := a.method()
-			if contains(tried, candidateMethod) {
+			if slices.Contains(tried, candidateMethod) {
 				continue
 			}
 			for _, meth := range methods {
@@ -117,15 +118,6 @@ func (c *connection) clientAuthenticate(config *ClientConfig) error {
 	return fmt.Errorf("ssh: unable to authenticate, attempted methods %v, no supported methods remain", tried)
 }
 
-func contains(list []string, e string) bool {
-	for _, s := range list {
-		if s == e {
-			return true
-		}
-	}
-	return false
-}
-
 // An AuthMethod represents an instance of an RFC 4252 authentication method.
 type AuthMethod interface {
 	// auth authenticates user over transport t.
@@ -255,7 +247,7 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiA
 		// Fallback to use if there is no "server-sig-algs" extension or a
 		// common algorithm cannot be found. We use the public key format if the
 		// MultiAlgorithmSigner supports it, otherwise we return an error.
-		if !contains(as.Algorithms(), underlyingAlgo(keyFormat)) {
+		if !slices.Contains(as.Algorithms(), underlyingAlgo(keyFormat)) {
 			return "", fmt.Errorf("ssh: no common public key signature algorithm, server only supports %q for key type %q, signer only supports %v",
 				underlyingAlgo(keyFormat), keyFormat, as.Algorithms())
 		}
@@ -284,7 +276,7 @@ func pickSignatureAlgorithm(signer Signer, extensions map[string][]byte) (MultiA
 	// Filter algorithms based on those supported by MultiAlgorithmSigner.
 	var keyAlgos []string
 	for _, algo := range algorithmsForKeyFormat(keyFormat) {
-		if contains(as.Algorithms(), underlyingAlgo(algo)) {
+		if slices.Contains(as.Algorithms(), underlyingAlgo(algo)) {
 			keyAlgos = append(keyAlgos, algo)
 		}
 	}
@@ -334,7 +326,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 		// the key try to use the obtained algorithm as if "server-sig-algs" had
 		// not been implemented if supported from the algorithm signer.
 		if !ok && idx < origSignersLen && isRSACert(algo) && algo != CertAlgoRSAv01 {
-			if contains(as.Algorithms(), KeyAlgoRSA) {
+			if slices.Contains(as.Algorithms(), KeyAlgoRSA) {
 				// We retry using the compat algorithm after all signers have
 				// been tried normally.
 				signers = append(signers, &multiAlgorithmSigner{
@@ -385,7 +377,7 @@ func (cb publicKeyCallback) auth(session []byte, user string, c packetConn, rand
 		// contain the "publickey" method, do not attempt to authenticate with any
 		// other keys.  According to RFC 4252 Section 7, the latter can occur when
 		// additional authentication methods are required.
-		if success == authSuccess || !contains(methods, cb.method()) {
+		if success == authSuccess || !slices.Contains(methods, cb.method()) {
 			return success, methods, err
 		}
 	}
@@ -434,7 +426,7 @@ func confirmKeyAck(key PublicKey, c packetConn) (bool, error) {
 			// servers send the key type instead. OpenSSH allows any algorithm
 			// that matches the public key, so we do the same.
 			// https://github.com/openssh/openssh-portable/blob/86bdd385/sshconnect2.c#L709
-			if !contains(algorithmsForKeyFormat(key.Type()), msg.Algo) {
+			if !slices.Contains(algorithmsForKeyFormat(key.Type()), msg.Algo) {
 				return false, nil
 			}
 			if !bytes.Equal(msg.PubKey, pubKey) {
diff --git a/vendor/golang.org/x/crypto/ssh/common.go b/vendor/golang.org/x/crypto/ssh/common.go
index 8bfad16c4..2e44e9c9e 100644
--- a/vendor/golang.org/x/crypto/ssh/common.go
+++ b/vendor/golang.org/x/crypto/ssh/common.go
@@ -6,6 +6,7 @@ package ssh
 
 import (
 	"crypto"
+	"crypto/fips140"
 	"crypto/rand"
 	"fmt"
 	"io"
@@ -256,6 +257,40 @@ type Algorithms struct {
 	PublicKeyAuths []string
 }
 
+func init() {
+	if fips140.Enabled() {
+		defaultHostKeyAlgos = slices.DeleteFunc(defaultHostKeyAlgos, func(algo string) bool {
+			_, err := hashFunc(underlyingAlgo(algo))
+			return err != nil
+		})
+		defaultPubKeyAuthAlgos = slices.DeleteFunc(defaultPubKeyAuthAlgos, func(algo string) bool {
+			_, err := hashFunc(underlyingAlgo(algo))
+			return err != nil
+		})
+	}
+}
+
+func hashFunc(format string) (crypto.Hash, error) {
+	switch format {
+	case KeyAlgoRSASHA256, KeyAlgoECDSA256, KeyAlgoSKED25519, KeyAlgoSKECDSA256:
+		return crypto.SHA256, nil
+	case KeyAlgoECDSA384:
+		return crypto.SHA384, nil
+	case KeyAlgoRSASHA512, KeyAlgoECDSA521:
+		return crypto.SHA512, nil
+	case KeyAlgoED25519:
+		// KeyAlgoED25519 doesn't pre-hash.
+		return 0, nil
+	case KeyAlgoRSA, InsecureKeyAlgoDSA:
+		if fips140.Enabled() {
+			return 0, fmt.Errorf("ssh: hash algorithm for format %q not allowed in FIPS 140 mode", format)
+		}
+		return crypto.SHA1, nil
+	default:
+		return 0, fmt.Errorf("ssh: hash algorithm for format %q not mapped", format)
+	}
+}
+
 // SupportedAlgorithms returns algorithms currently implemented by this package,
 // excluding those with security issues, which are returned by
 // InsecureAlgorithms. The algorithms listed here are in preference order.
@@ -283,21 +318,6 @@ func InsecureAlgorithms() Algorithms {
 
 var supportedCompressions = []string{compressionNone}
 
-// hashFuncs keeps the mapping of supported signature algorithms to their
-// respective hashes needed for signing and verification.
-var hashFuncs = map[string]crypto.Hash{
-	KeyAlgoRSA:         crypto.SHA1,
-	KeyAlgoRSASHA256:   crypto.SHA256,
-	KeyAlgoRSASHA512:   crypto.SHA512,
-	InsecureKeyAlgoDSA: crypto.SHA1,
-	KeyAlgoECDSA256:    crypto.SHA256,
-	KeyAlgoECDSA384:    crypto.SHA384,
-	KeyAlgoECDSA521:    crypto.SHA512,
-	// KeyAlgoED25519 doesn't pre-hash.
-	KeyAlgoSKECDSA256: crypto.SHA256,
-	KeyAlgoSKED25519:  crypto.SHA256,
-}
-
 // algorithmsForKeyFormat returns the supported signature algorithms for a given
 // public key format (PublicKey.Type), in order of preference. See RFC 8332,
 // Section 2. See also the note in sendKexInit on backwards compatibility.
@@ -312,11 +332,40 @@ func algorithmsForKeyFormat(keyFormat string) []string {
 	}
 }
 
+// keyFormatForAlgorithm returns the key format corresponding to the given
+// signature algorithm. It returns an empty string if the signature algorithm is
+// invalid or unsupported.
+func keyFormatForAlgorithm(sigAlgo string) string {
+	switch sigAlgo {
+	case KeyAlgoRSA, KeyAlgoRSASHA256, KeyAlgoRSASHA512:
+		return KeyAlgoRSA
+	case CertAlgoRSAv01, CertAlgoRSASHA256v01, CertAlgoRSASHA512v01:
+		return CertAlgoRSAv01
+	case KeyAlgoED25519,
+		KeyAlgoSKED25519,
+		KeyAlgoSKECDSA256,
+		KeyAlgoECDSA256,
+		KeyAlgoECDSA384,
+		KeyAlgoECDSA521,
+		InsecureKeyAlgoDSA,
+		InsecureCertAlgoDSAv01,
+		CertAlgoECDSA256v01,
+		CertAlgoECDSA384v01,
+		CertAlgoECDSA521v01,
+		CertAlgoSKECDSA256v01,
+		CertAlgoED25519v01,
+		CertAlgoSKED25519v01:
+		return sigAlgo
+	default:
+		return ""
+	}
+}
+
 // isRSA returns whether algo is a supported RSA algorithm, including certificate
 // algorithms.
 func isRSA(algo string) bool {
 	algos := algorithmsForKeyFormat(KeyAlgoRSA)
-	return contains(algos, underlyingAlgo(algo))
+	return slices.Contains(algos, underlyingAlgo(algo))
 }
 
 func isRSACert(algo string) bool {
@@ -515,7 +564,7 @@ func (c *Config) SetDefaults() {
 		if kexAlgoMap[k] != nil {
 			// Ignore the KEX if we have no kexAlgoMap definition.
 			kexs = append(kexs, k)
-			if k == KeyExchangeCurve25519 && !contains(c.KeyExchanges, keyExchangeCurve25519LibSSH) {
+			if k == KeyExchangeCurve25519 && !slices.Contains(c.KeyExchanges, keyExchangeCurve25519LibSSH) {
 				kexs = append(kexs, keyExchangeCurve25519LibSSH)
 			}
 		}
diff --git a/vendor/golang.org/x/crypto/ssh/doc.go b/vendor/golang.org/x/crypto/ssh/doc.go
index 04ccce346..5b4de9eff 100644
--- a/vendor/golang.org/x/crypto/ssh/doc.go
+++ b/vendor/golang.org/x/crypto/ssh/doc.go
@@ -17,8 +17,18 @@ References:
 	[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
 	[SSH-PARAMETERS]:    http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
 	[SSH-CERTS]:	https://datatracker.ietf.org/doc/html/draft-miller-ssh-cert-01
+	[FIPS 140-3 mode]: https://go.dev/doc/security/fips140
 
 This package does not fall under the stability promise of the Go language itself,
 so its API may be changed when pressing needs arise.
+
+# FIPS 140-3 mode
+
+When the program is in [FIPS 140-3 mode], this package behaves as if only SP
+800-140C and SP 800-140D approved cipher suites, signature algorithms,
+certificate public key types and sizes, and key exchange and derivation
+algorithms were implemented. Others are silently ignored and not negotiated, or
+rejected. This set may depend on the algorithms supported by the FIPS 140-3 Go
+Cryptographic Module selected with GOFIPS140, and may change across Go versions.
 */
 package ssh
diff --git a/vendor/golang.org/x/crypto/ssh/handshake.go b/vendor/golang.org/x/crypto/ssh/handshake.go
index a90bfe331..4be3cbb6d 100644
--- a/vendor/golang.org/x/crypto/ssh/handshake.go
+++ b/vendor/golang.org/x/crypto/ssh/handshake.go
@@ -10,6 +10,7 @@ import (
 	"io"
 	"log"
 	"net"
+	"slices"
 	"strings"
 	"sync"
 )
@@ -527,7 +528,7 @@ func (t *handshakeTransport) sendKexInit() error {
 			switch s := k.(type) {
 			case MultiAlgorithmSigner:
 				for _, algo := range algorithmsForKeyFormat(keyFormat) {
-					if contains(s.Algorithms(), underlyingAlgo(algo)) {
+					if slices.Contains(s.Algorithms(), underlyingAlgo(algo)) {
 						msg.ServerHostKeyAlgos = append(msg.ServerHostKeyAlgos, algo)
 					}
 				}
@@ -679,7 +680,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
 		return err
 	}
 
-	if t.sessionID == nil && ((isClient && contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && contains(clientInit.KexAlgos, kexStrictClient))) {
+	if t.sessionID == nil && ((isClient && slices.Contains(serverInit.KexAlgos, kexStrictServer)) || (!isClient && slices.Contains(clientInit.KexAlgos, kexStrictClient))) {
 		t.strictMode = true
 		if err := t.conn.setStrictMode(); err != nil {
 			return err
@@ -736,7 +737,7 @@ func (t *handshakeTransport) enterKeyExchange(otherInitPacket []byte) error {
 	// On the server side, after the first SSH_MSG_NEWKEYS, send a SSH_MSG_EXT_INFO
 	// message with the server-sig-algs extension if the client supports it. See
 	// RFC 8308, Sections 2.4 and 3.1, and [PROTOCOL], Section 1.9.
-	if !isClient && firstKeyExchange && contains(clientInit.KexAlgos, "ext-info-c") {
+	if !isClient && firstKeyExchange && slices.Contains(clientInit.KexAlgos, "ext-info-c") {
 		supportedPubKeyAuthAlgosList := strings.Join(t.publicKeyAuthAlgorithms, ",")
 		extInfo := &extInfoMsg{
 			NumExtensions: 2,
@@ -790,7 +791,7 @@ func (a algorithmSignerWrapper) SignWithAlgorithm(rand io.Reader, data []byte, a
 func pickHostKey(hostKeys []Signer, algo string) AlgorithmSigner {
 	for _, k := range hostKeys {
 		if s, ok := k.(MultiAlgorithmSigner); ok {
-			if !contains(s.Algorithms(), underlyingAlgo(algo)) {
+			if !slices.Contains(s.Algorithms(), underlyingAlgo(algo)) {
 				continue
 			}
 		}
diff --git a/vendor/golang.org/x/crypto/ssh/kex.go b/vendor/golang.org/x/crypto/ssh/kex.go
index 78aaf0310..5f7fdd851 100644
--- a/vendor/golang.org/x/crypto/ssh/kex.go
+++ b/vendor/golang.org/x/crypto/ssh/kex.go
@@ -8,12 +8,14 @@ import (
 	"crypto"
 	"crypto/ecdsa"
 	"crypto/elliptic"
+	"crypto/fips140"
 	"crypto/rand"
 	"encoding/binary"
 	"errors"
 	"fmt"
 	"io"
 	"math/big"
+	"slices"
 
 	"golang.org/x/crypto/curve25519"
 )
@@ -395,9 +397,27 @@ func ecHash(curve elliptic.Curve) crypto.Hash {
 	return crypto.SHA512
 }
 
+// kexAlgoMap defines the supported KEXs. KEXs not included are not supported
+// and will not be negotiated, even if explicitly configured. When FIPS mode is
+// enabled, only FIPS-approved algorithms are included.
 var kexAlgoMap = map[string]kexAlgorithm{}
 
 func init() {
+	// mlkem768x25519-sha256 we'll work with fips140=on but not fips140=only
+	// until Go 1.26.
+	kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{}
+	kexAlgoMap[KeyExchangeECDHP521] = &ecdh{elliptic.P521()}
+	kexAlgoMap[KeyExchangeECDHP384] = &ecdh{elliptic.P384()}
+	kexAlgoMap[KeyExchangeECDHP256] = &ecdh{elliptic.P256()}
+
+	if fips140.Enabled() {
+		defaultKexAlgos = slices.DeleteFunc(defaultKexAlgos, func(algo string) bool {
+			_, ok := kexAlgoMap[algo]
+			return !ok
+		})
+		return
+	}
+
 	p, _ := new(big.Int).SetString(oakleyGroup2, 16)
 	kexAlgoMap[InsecureKeyExchangeDH1SHA1] = &dhGroup{
 		g:        new(big.Int).SetInt64(2),
@@ -431,14 +451,10 @@ func init() {
 		hashFunc: crypto.SHA512,
 	}
 
-	kexAlgoMap[KeyExchangeECDHP521] = &ecdh{elliptic.P521()}
-	kexAlgoMap[KeyExchangeECDHP384] = &ecdh{elliptic.P384()}
-	kexAlgoMap[KeyExchangeECDHP256] = &ecdh{elliptic.P256()}
 	kexAlgoMap[KeyExchangeCurve25519] = &curve25519sha256{}
 	kexAlgoMap[keyExchangeCurve25519LibSSH] = &curve25519sha256{}
 	kexAlgoMap[InsecureKeyExchangeDHGEXSHA1] = &dhGEXSHA{hashFunc: crypto.SHA1}
 	kexAlgoMap[KeyExchangeDHGEXSHA256] = &dhGEXSHA{hashFunc: crypto.SHA256}
-	kexAlgoMap[KeyExchangeMLKEM768X25519] = &mlkem768WithCurve25519sha256{}
 }
 
 // curve25519sha256 implements the curve25519-sha256 (formerly known as
diff --git a/vendor/golang.org/x/crypto/ssh/keys.go b/vendor/golang.org/x/crypto/ssh/keys.go
index a28c0de50..a035956fc 100644
--- a/vendor/golang.org/x/crypto/ssh/keys.go
+++ b/vendor/golang.org/x/crypto/ssh/keys.go
@@ -27,6 +27,7 @@ import (
 	"fmt"
 	"io"
 	"math/big"
+	"slices"
 	"strings"
 
 	"golang.org/x/crypto/ssh/internal/bcrypt_pbkdf"
@@ -89,6 +90,11 @@ func parsePubKey(in []byte, algo string) (pubKey PublicKey, rest []byte, err err
 		}
 		return cert, nil, nil
 	}
+	if keyFormat := keyFormatForAlgorithm(algo); keyFormat != "" {
+		return nil, nil, fmt.Errorf("ssh: signature algorithm %q isn't a key format; key is malformed and should be re-encoded with type %q",
+			algo, keyFormat)
+	}
+
 	return nil, nil, fmt.Errorf("ssh: unknown key algorithm: %v", algo)
 }
 
@@ -191,9 +197,10 @@ func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey
 	return "", nil, nil, "", nil, io.EOF
 }
 
-// ParseAuthorizedKey parses a public key from an authorized_keys
-// file used in OpenSSH according to the sshd(8) manual page.
+// ParseAuthorizedKey parses a public key from an authorized_keys file used in
+// OpenSSH according to the sshd(8) manual page. Invalid lines are ignored.
 func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error) {
+	var lastErr error
 	for len(in) > 0 {
 		end := bytes.IndexByte(in, '\n')
 		if end != -1 {
@@ -222,6 +229,8 @@ func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []str
 
 		if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
 			return out, comment, options, rest, nil
+		} else {
+			lastErr = err
 		}
 
 		// No key type recognised. Maybe there's an options field at
@@ -264,12 +273,18 @@ func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []str
 		if out, comment, err = parseAuthorizedKey(in[i:]); err == nil {
 			options = candidateOptions
 			return out, comment, options, rest, nil
+		} else {
+			lastErr = err
 		}
 
 		in = rest
 		continue
 	}
 
+	if lastErr != nil {
+		return nil, "", nil, nil, fmt.Errorf("ssh: no key found; last parsing error for ignored line: %w", lastErr)
+	}
+
 	return nil, "", nil, nil, errors.New("ssh: no key found")
 }
 
@@ -395,11 +410,11 @@ func NewSignerWithAlgorithms(signer AlgorithmSigner, algorithms []string) (Multi
 	}
 
 	for _, algo := range algorithms {
-		if !contains(supportedAlgos, algo) {
+		if !slices.Contains(supportedAlgos, algo) {
 			return nil, fmt.Errorf("ssh: algorithm %q is not supported for key type %q",
 				algo, signer.PublicKey().Type())
 		}
-		if !contains(signerAlgos, algo) {
+		if !slices.Contains(signerAlgos, algo) {
 			return nil, fmt.Errorf("ssh: algorithm %q is restricted for the provided signer", algo)
 		}
 	}
@@ -486,10 +501,13 @@ func (r *rsaPublicKey) Marshal() []byte {
 
 func (r *rsaPublicKey) Verify(data []byte, sig *Signature) error {
 	supportedAlgos := algorithmsForKeyFormat(r.Type())
-	if !contains(supportedAlgos, sig.Format) {
+	if !slices.Contains(supportedAlgos, sig.Format) {
 		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, r.Type())
 	}
-	hash := hashFuncs[sig.Format]
+	hash, err := hashFunc(sig.Format)
+	if err != nil {
+		return err
+	}
 	h := hash.New()
 	h.Write(data)
 	digest := h.Sum(nil)
@@ -606,7 +624,11 @@ func (k *dsaPublicKey) Verify(data []byte, sig *Signature) error {
 	if sig.Format != k.Type() {
 		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 	}
-	h := hashFuncs[sig.Format].New()
+	hash, err := hashFunc(sig.Format)
+	if err != nil {
+		return err
+	}
+	h := hash.New()
 	h.Write(data)
 	digest := h.Sum(nil)
 
@@ -651,7 +673,11 @@ func (k *dsaPrivateKey) SignWithAlgorithm(rand io.Reader, data []byte, algorithm
 		return nil, fmt.Errorf("ssh: unsupported signature algorithm %s", algorithm)
 	}
 
-	h := hashFuncs[k.PublicKey().Type()].New()
+	hash, err := hashFunc(k.PublicKey().Type())
+	if err != nil {
+		return nil, err
+	}
+	h := hash.New()
 	h.Write(data)
 	digest := h.Sum(nil)
 	r, s, err := dsa.Sign(rand, k.PrivateKey, digest)
@@ -801,8 +827,11 @@ func (k *ecdsaPublicKey) Verify(data []byte, sig *Signature) error {
 	if sig.Format != k.Type() {
 		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 	}
-
-	h := hashFuncs[sig.Format].New()
+	hash, err := hashFunc(sig.Format)
+	if err != nil {
+		return err
+	}
+	h := hash.New()
 	h.Write(data)
 	digest := h.Sum(nil)
 
@@ -905,8 +934,11 @@ func (k *skECDSAPublicKey) Verify(data []byte, sig *Signature) error {
 	if sig.Format != k.Type() {
 		return fmt.Errorf("ssh: signature type %s for key type %s", sig.Format, k.Type())
 	}
-
-	h := hashFuncs[sig.Format].New()
+	hash, err := hashFunc(sig.Format)
+	if err != nil {
+		return err
+	}
+	h := hash.New()
 	h.Write([]byte(k.application))
 	appDigest := h.Sum(nil)
 
@@ -1009,7 +1041,11 @@ func (k *skEd25519PublicKey) Verify(data []byte, sig *Signature) error {
 		return fmt.Errorf("invalid size %d for Ed25519 public key", l)
 	}
 
-	h := hashFuncs[sig.Format].New()
+	hash, err := hashFunc(sig.Format)
+	if err != nil {
+		return err
+	}
+	h := hash.New()
 	h.Write([]byte(k.application))
 	appDigest := h.Sum(nil)
 
@@ -1112,11 +1148,14 @@ func (s *wrappedSigner) SignWithAlgorithm(rand io.Reader, data []byte, algorithm
 		algorithm = s.pubKey.Type()
 	}
 
-	if !contains(s.Algorithms(), algorithm) {
+	if !slices.Contains(s.Algorithms(), algorithm) {
 		return nil, fmt.Errorf("ssh: unsupported signature algorithm %q for key format %q", algorithm, s.pubKey.Type())
 	}
 
-	hashFunc := hashFuncs[algorithm]
+	hashFunc, err := hashFunc(algorithm)
+	if err != nil {
+		return nil, err
+	}
 	var digest []byte
 	if hashFunc != 0 {
 		h := hashFunc.New()
diff --git a/vendor/golang.org/x/crypto/ssh/mac.go b/vendor/golang.org/x/crypto/ssh/mac.go
index de2639d57..87d626fbb 100644
--- a/vendor/golang.org/x/crypto/ssh/mac.go
+++ b/vendor/golang.org/x/crypto/ssh/mac.go
@@ -7,11 +7,13 @@ package ssh
 // Message authentication support
 
 import (
+	"crypto/fips140"
 	"crypto/hmac"
 	"crypto/sha1"
 	"crypto/sha256"
 	"crypto/sha512"
 	"hash"
+	"slices"
 )
 
 type macMode struct {
@@ -46,23 +48,37 @@ func (t truncatingMAC) Size() int {
 
 func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() }
 
-var macModes = map[string]*macMode{
-	HMACSHA512ETM: {64, true, func(key []byte) hash.Hash {
+// macModes defines the supported MACs. MACs not included are not supported
+// and will not be negotiated, even if explicitly configured. When FIPS mode is
+// enabled, only FIPS-approved algorithms are included.
+var macModes = map[string]*macMode{}
+
+func init() {
+	macModes[HMACSHA512ETM] = &macMode{64, true, func(key []byte) hash.Hash {
 		return hmac.New(sha512.New, key)
-	}},
-	HMACSHA256ETM: {32, true, func(key []byte) hash.Hash {
+	}}
+	macModes[HMACSHA256ETM] = &macMode{32, true, func(key []byte) hash.Hash {
 		return hmac.New(sha256.New, key)
-	}},
-	HMACSHA512: {64, false, func(key []byte) hash.Hash {
+	}}
+	macModes[HMACSHA512] = &macMode{64, false, func(key []byte) hash.Hash {
 		return hmac.New(sha512.New, key)
-	}},
-	HMACSHA256: {32, false, func(key []byte) hash.Hash {
+	}}
+	macModes[HMACSHA256] = &macMode{32, false, func(key []byte) hash.Hash {
 		return hmac.New(sha256.New, key)
-	}},
-	HMACSHA1: {20, false, func(key []byte) hash.Hash {
+	}}
+
+	if fips140.Enabled() {
+		defaultMACs = slices.DeleteFunc(defaultMACs, func(algo string) bool {
+			_, ok := macModes[algo]
+			return !ok
+		})
+		return
+	}
+
+	macModes[HMACSHA1] = &macMode{20, false, func(key []byte) hash.Hash {
 		return hmac.New(sha1.New, key)
-	}},
-	InsecureHMACSHA196: {20, false, func(key []byte) hash.Hash {
+	}}
+	macModes[InsecureHMACSHA196] = &macMode{20, false, func(key []byte) hash.Hash {
 		return truncatingMAC{12, hmac.New(sha1.New, key)}
-	}},
+	}}
 }
diff --git a/vendor/golang.org/x/crypto/ssh/server.go b/vendor/golang.org/x/crypto/ssh/server.go
index 98679ba5b..064dcbaf5 100644
--- a/vendor/golang.org/x/crypto/ssh/server.go
+++ b/vendor/golang.org/x/crypto/ssh/server.go
@@ -10,6 +10,7 @@ import (
 	"fmt"
 	"io"
 	"net"
+	"slices"
 	"strings"
 )
 
@@ -43,6 +44,9 @@ type Permissions struct {
 	// pass data from the authentication callbacks to the server
 	// application layer.
 	Extensions map[string]string
+
+	// ExtraData allows to store user defined data.
+	ExtraData map[any]any
 }
 
 type GSSAPIWithMICConfig struct {
@@ -126,6 +130,21 @@ type ServerConfig struct {
 	// Permissions.Extensions entry.
 	PublicKeyCallback func(conn ConnMetadata, key PublicKey) (*Permissions, error)
 
+	// VerifiedPublicKeyCallback, if non-nil, is called after a client
+	// successfully confirms having control over a key that was previously
+	// approved by PublicKeyCallback. The permissions object passed to the
+	// callback is the one returned by PublicKeyCallback for the given public
+	// key and its ownership is transferred to the callback. The returned
+	// Permissions object can be the same object, optionally modified, or a
+	// completely new object. If VerifiedPublicKeyCallback is non-nil,
+	// PublicKeyCallback is not allowed to return a PartialSuccessError, which
+	// can instead be returned by VerifiedPublicKeyCallback.
+	//
+	// VerifiedPublicKeyCallback does not affect which authentication methods
+	// are included in the list of methods that can be attempted by the client.
+	VerifiedPublicKeyCallback func(conn ConnMetadata, key PublicKey, permissions *Permissions,
+		signatureAlgorithm string) (*Permissions, error)
+
 	// KeyboardInteractiveCallback, if non-nil, is called when
 	// keyboard-interactive authentication is selected (RFC
 	// 4256). The client object's Challenge function should be
@@ -246,7 +265,7 @@ func NewServerConn(c net.Conn, config *ServerConfig) (*ServerConn, <-chan NewCha
 		fullConf.PublicKeyAuthAlgorithms = defaultPubKeyAuthAlgos
 	} else {
 		for _, algo := range fullConf.PublicKeyAuthAlgorithms {
-			if !contains(SupportedAlgorithms().PublicKeyAuths, algo) && !contains(InsecureAlgorithms().PublicKeyAuths, algo) {
+			if !slices.Contains(SupportedAlgorithms().PublicKeyAuths, algo) && !slices.Contains(InsecureAlgorithms().PublicKeyAuths, algo) {
 				c.Close()
 				return nil, nil, nil, fmt.Errorf("ssh: unsupported public key authentication algorithm %s", algo)
 			}
@@ -631,7 +650,7 @@ userAuthLoop:
 				return nil, parseError(msgUserAuthRequest)
 			}
 			algo := string(algoBytes)
-			if !contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) {
+			if !slices.Contains(config.PublicKeyAuthAlgorithms, underlyingAlgo(algo)) {
 				authErr = fmt.Errorf("ssh: algorithm %q not accepted", algo)
 				break
 			}
@@ -652,6 +671,9 @@ userAuthLoop:
 				candidate.pubKeyData = pubKeyData
 				candidate.perms, candidate.result = authConfig.PublicKeyCallback(s, pubKey)
 				_, isPartialSuccessError := candidate.result.(*PartialSuccessError)
+				if isPartialSuccessError && config.VerifiedPublicKeyCallback != nil {
+					return nil, errors.New("ssh: invalid library usage: PublicKeyCallback must not return partial success when VerifiedPublicKeyCallback is defined")
+				}
 
 				if (candidate.result == nil || isPartialSuccessError) &&
 					candidate.perms != nil &&
@@ -695,7 +717,7 @@ userAuthLoop:
 				// ssh-rsa-cert-v01@openssh.com algorithm with ssh-rsa public
 				// key type. The algorithm and public key type must be
 				// consistent: both must be certificate algorithms, or neither.
-				if !contains(algorithmsForKeyFormat(pubKey.Type()), algo) {
+				if !slices.Contains(algorithmsForKeyFormat(pubKey.Type()), algo) {
 					authErr = fmt.Errorf("ssh: public key type %q not compatible with selected algorithm %q",
 						pubKey.Type(), algo)
 					break
@@ -705,7 +727,7 @@ userAuthLoop:
 				// algorithm name that corresponds to algo with
 				// sig.Format.  This is usually the same, but
 				// for certs, the names differ.
-				if !contains(config.PublicKeyAuthAlgorithms, sig.Format) {
+				if !slices.Contains(config.PublicKeyAuthAlgorithms, sig.Format) {
 					authErr = fmt.Errorf("ssh: algorithm %q not accepted", sig.Format)
 					break
 				}
@@ -722,6 +744,12 @@ userAuthLoop:
 
 				authErr = candidate.result
 				perms = candidate.perms
+				if authErr == nil && config.VerifiedPublicKeyCallback != nil {
+					// Only call VerifiedPublicKeyCallback after the key has been accepted
+					// and successfully verified. If authErr is non-nil, the key is not
+					// considered verified and the callback must not run.
+					perms, authErr = config.VerifiedPublicKeyCallback(s, pubKey, perms, algo)
+				}
 			}
 		case "gssapi-with-mic":
 			if authConfig.GSSAPIWithMICConfig == nil {
diff --git a/vendor/golang.org/x/crypto/ssh/transport.go b/vendor/golang.org/x/crypto/ssh/transport.go
index 663619845..fa3dd6a42 100644
--- a/vendor/golang.org/x/crypto/ssh/transport.go
+++ b/vendor/golang.org/x/crypto/ssh/transport.go
@@ -8,6 +8,7 @@ import (
 	"bufio"
 	"bytes"
 	"errors"
+	"fmt"
 	"io"
 	"log"
 )
@@ -254,6 +255,9 @@ var (
 // (to setup server->client keys) or clientKeys (for client->server keys).
 func newPacketCipher(d direction, algs DirectionAlgorithms, kex *kexResult) (packetCipher, error) {
 	cipherMode := cipherModes[algs.Cipher]
+	if cipherMode == nil {
+		return nil, fmt.Errorf("ssh: unsupported cipher %v", algs.Cipher)
+	}
 
 	iv := make([]byte, cipherMode.ivSize)
 	key := make([]byte, cipherMode.keySize)
diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go
index 04c6bec21..12f227370 100644
--- a/vendor/golang.org/x/net/html/escape.go
+++ b/vendor/golang.org/x/net/html/escape.go
@@ -299,7 +299,7 @@ func escape(w writer, s string) error {
 		case '\r':
 			esc = "&#13;"
 		default:
-			panic("unrecognized escape character")
+			panic("html: unrecognized escape character")
 		}
 		s = s[i+1:]
 		if _, err := w.WriteString(esc); err != nil {
diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go
index 518ee4c94..88fc0056a 100644
--- a/vendor/golang.org/x/net/html/parse.go
+++ b/vendor/golang.org/x/net/html/parse.go
@@ -136,7 +136,7 @@ func (p *parser) indexOfElementInScope(s scope, matchTags ...a.Atom) int {
 					return -1
 				}
 			default:
-				panic("unreachable")
+				panic(fmt.Sprintf("html: internal error: indexOfElementInScope unknown scope: %d", s))
 			}
 		}
 		switch s {
@@ -179,7 +179,7 @@ func (p *parser) clearStackToContext(s scope) {
 				return
 			}
 		default:
-			panic("unreachable")
+			panic(fmt.Sprintf("html: internal error: clearStackToContext unknown scope: %d", s))
 		}
 	}
 }
@@ -231,7 +231,14 @@ func (p *parser) addChild(n *Node) {
 	}
 
 	if n.Type == ElementNode {
-		p.oe = append(p.oe, n)
+		p.insertOpenElement(n)
+	}
+}
+
+func (p *parser) insertOpenElement(n *Node) {
+	p.oe = append(p.oe, n)
+	if len(p.oe) > 512 {
+		panic("html: open stack of elements exceeds 512 nodes")
 	}
 }
 
@@ -810,7 +817,7 @@ func afterHeadIM(p *parser) bool {
 			p.im = inFramesetIM
 			return true
 		case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Script, a.Style, a.Template, a.Title:
-			p.oe = append(p.oe, p.head)
+			p.insertOpenElement(p.head)
 			defer p.oe.remove(p.head)
 			return inHeadIM(p)
 		case a.Head:
@@ -1678,7 +1685,7 @@ func inTableBodyIM(p *parser) bool {
 	return inTableIM(p)
 }
 
-// Section 12.2.6.4.14.
+// Section 13.2.6.4.14.
 func inRowIM(p *parser) bool {
 	switch p.tok.Type {
 	case StartTagToken:
@@ -1690,7 +1697,9 @@ func inRowIM(p *parser) bool {
 			p.im = inCellIM
 			return true
 		case a.Caption, a.Col, a.Colgroup, a.Tbody, a.Tfoot, a.Thead, a.Tr:
-			if p.popUntil(tableScope, a.Tr) {
+			if p.elementInScope(tableScope, a.Tr) {
+				p.clearStackToContext(tableRowScope)
+				p.oe.pop()
 				p.im = inTableBodyIM
 				return false
 			}
@@ -1700,22 +1709,28 @@ func inRowIM(p *parser) bool {
 	case EndTagToken:
 		switch p.tok.DataAtom {
 		case a.Tr:
-			if p.popUntil(tableScope, a.Tr) {
+			if p.elementInScope(tableScope, a.Tr) {
+				p.clearStackToContext(tableRowScope)
+				p.oe.pop()
 				p.im = inTableBodyIM
 				return true
 			}
 			// Ignore the token.
 			return true
 		case a.Table:
-			if p.popUntil(tableScope, a.Tr) {
+			if p.elementInScope(tableScope, a.Tr) {
+				p.clearStackToContext(tableRowScope)
+				p.oe.pop()
 				p.im = inTableBodyIM
 				return false
 			}
 			// Ignore the token.
 			return true
 		case a.Tbody, a.Tfoot, a.Thead:
-			if p.elementInScope(tableScope, p.tok.DataAtom) {
-				p.parseImpliedToken(EndTagToken, a.Tr, a.Tr.String())
+			if p.elementInScope(tableScope, p.tok.DataAtom) && p.elementInScope(tableScope, a.Tr) {
+				p.clearStackToContext(tableRowScope)
+				p.oe.pop()
+				p.im = inTableBodyIM
 				return false
 			}
 			// Ignore the token.
@@ -2222,16 +2237,20 @@ func parseForeignContent(p *parser) bool {
 			p.acknowledgeSelfClosingTag()
 		}
 	case EndTagToken:
+		if strings.EqualFold(p.oe[len(p.oe)-1].Data, p.tok.Data) {
+			p.oe = p.oe[:len(p.oe)-1]
+			return true
+		}
 		for i := len(p.oe) - 1; i >= 0; i-- {
-			if p.oe[i].Namespace == "" {
-				return p.im(p)
-			}
 			if strings.EqualFold(p.oe[i].Data, p.tok.Data) {
 				p.oe = p.oe[:i]
+				return true
+			}
+			if i > 0 && p.oe[i-1].Namespace == "" {
 				break
 			}
 		}
-		return true
+		return p.im(p)
 	default:
 		// Ignore the token.
 	}
@@ -2312,9 +2331,13 @@ func (p *parser) parseCurrentToken() {
 	}
 }
 
-func (p *parser) parse() error {
+func (p *parser) parse() (err error) {
+	defer func() {
+		if panicErr := recover(); panicErr != nil {
+			err = fmt.Errorf("%s", panicErr)
+		}
+	}()
 	// Iterate until EOF. Any other error will cause an early return.
-	var err error
 	for err != io.EOF {
 		// CDATA sections are allowed only in foreign content.
 		n := p.oe.top()
@@ -2343,6 +2366,8 @@ func (p *parser) parse() error {
 // <tag>s. Conversely, explicit <tag>s in r's data can be silently dropped,
 // with no corresponding node in the resulting tree.
 //
+// Parse will reject HTML that is nested deeper than 512 elements.
+//
 // The input is assumed to be UTF-8 encoded.
 func Parse(r io.Reader) (*Node, error) {
 	return ParseWithOptions(r)
diff --git a/vendor/golang.org/x/net/html/render.go b/vendor/golang.org/x/net/html/render.go
index e8c123345..0157d89e1 100644
--- a/vendor/golang.org/x/net/html/render.go
+++ b/vendor/golang.org/x/net/html/render.go
@@ -184,7 +184,7 @@ func render1(w writer, n *Node) error {
 		return err
 	}
 
-	// Add initial newline where there is danger of a newline beging ignored.
+	// Add initial newline where there is danger of a newline being ignored.
 	if c := n.FirstChild; c != nil && c.Type == TextNode && strings.HasPrefix(c.Data, "\n") {
 		switch n.Data {
 		case "pre", "listing", "textarea":
diff --git a/vendor/golang.org/x/net/http2/config.go b/vendor/golang.org/x/net/http2/config.go
index 02fe0c2d4..8a7a89d01 100644
--- a/vendor/golang.org/x/net/http2/config.go
+++ b/vendor/golang.org/x/net/http2/config.go
@@ -27,6 +27,7 @@ import (
 //   - If the resulting value is zero or out of range, use a default.
 type http2Config struct {
 	MaxConcurrentStreams         uint32
+	StrictMaxConcurrentRequests  bool
 	MaxDecoderHeaderTableSize    uint32
 	MaxEncoderHeaderTableSize    uint32
 	MaxReadFrameSize             uint32
@@ -64,12 +65,13 @@ func configFromServer(h1 *http.Server, h2 *Server) http2Config {
 // (the net/http Transport).
 func configFromTransport(h2 *Transport) http2Config {
 	conf := http2Config{
-		MaxEncoderHeaderTableSize: h2.MaxEncoderHeaderTableSize,
-		MaxDecoderHeaderTableSize: h2.MaxDecoderHeaderTableSize,
-		MaxReadFrameSize:          h2.MaxReadFrameSize,
-		SendPingTimeout:           h2.ReadIdleTimeout,
-		PingTimeout:               h2.PingTimeout,
-		WriteByteTimeout:          h2.WriteByteTimeout,
+		StrictMaxConcurrentRequests: h2.StrictMaxConcurrentStreams,
+		MaxEncoderHeaderTableSize:   h2.MaxEncoderHeaderTableSize,
+		MaxDecoderHeaderTableSize:   h2.MaxDecoderHeaderTableSize,
+		MaxReadFrameSize:            h2.MaxReadFrameSize,
+		SendPingTimeout:             h2.ReadIdleTimeout,
+		PingTimeout:                 h2.PingTimeout,
+		WriteByteTimeout:            h2.WriteByteTimeout,
 	}
 
 	// Unlike most config fields, where out-of-range values revert to the default,
@@ -128,6 +130,9 @@ func fillNetHTTPConfig(conf *http2Config, h2 *http.HTTP2Config) {
 	if h2.MaxConcurrentStreams != 0 {
 		conf.MaxConcurrentStreams = uint32(h2.MaxConcurrentStreams)
 	}
+	if http2ConfigStrictMaxConcurrentRequests(h2) {
+		conf.StrictMaxConcurrentRequests = true
+	}
 	if h2.MaxEncoderHeaderTableSize != 0 {
 		conf.MaxEncoderHeaderTableSize = uint32(h2.MaxEncoderHeaderTableSize)
 	}
diff --git a/vendor/golang.org/x/net/http2/config_go125.go b/vendor/golang.org/x/net/http2/config_go125.go
new file mode 100644
index 000000000..b4373fe33
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/config_go125.go
@@ -0,0 +1,15 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.26
+
+package http2
+
+import (
+	"net/http"
+)
+
+func http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool {
+	return false
+}
diff --git a/vendor/golang.org/x/net/http2/config_go126.go b/vendor/golang.org/x/net/http2/config_go126.go
new file mode 100644
index 000000000..6b071c149
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/config_go126.go
@@ -0,0 +1,15 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.26
+
+package http2
+
+import (
+	"net/http"
+)
+
+func http2ConfigStrictMaxConcurrentRequests(h2 *http.HTTP2Config) bool {
+	return h2.StrictMaxConcurrentRequests
+}
diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go
index db3264da8..93bcaab03 100644
--- a/vendor/golang.org/x/net/http2/frame.go
+++ b/vendor/golang.org/x/net/http2/frame.go
@@ -347,7 +347,7 @@ func (fr *Framer) maxHeaderListSize() uint32 {
 func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
 	// Write the FrameHeader.
 	f.wbuf = append(f.wbuf[:0],
-		0, // 3 bytes of length, filled in in endWrite
+		0, // 3 bytes of length, filled in endWrite
 		0,
 		0,
 		byte(ftype),
@@ -1152,6 +1152,15 @@ type PriorityFrame struct {
 	PriorityParam
 }
 
+var defaultRFC9218Priority = PriorityParam{
+	incremental: 0,
+	urgency:     3,
+}
+
+// Note that HTTP/2 has had two different prioritization schemes, and
+// PriorityParam struct below is a superset of both schemes. The exported
+// symbols are from RFC 7540 and the non-exported ones are from RFC 9218.
+
 // PriorityParam are the stream prioritzation parameters.
 type PriorityParam struct {
 	// StreamDep is a 31-bit stream identifier for the
@@ -1167,6 +1176,20 @@ type PriorityParam struct {
 	// the spec, "Add one to the value to obtain a weight between
 	// 1 and 256."
 	Weight uint8
+
+	// "The urgency (u) parameter value is Integer (see Section 3.3.1 of
+	// [STRUCTURED-FIELDS]), between 0 and 7 inclusive, in descending order of
+	// priority. The default is 3."
+	urgency uint8
+
+	// "The incremental (i) parameter value is Boolean (see Section 3.3.6 of
+	// [STRUCTURED-FIELDS]). It indicates if an HTTP response can be processed
+	// incrementally, i.e., provide some meaningful output as chunks of the
+	// response arrive."
+	//
+	// We use uint8 (i.e. 0 is false, 1 is true) instead of bool so we can
+	// avoid unnecessary type conversions and because either type takes 1 byte.
+	incremental uint8
 }
 
 func (p PriorityParam) IsZero() bool {
diff --git a/vendor/golang.org/x/net/http2/http2.go b/vendor/golang.org/x/net/http2/http2.go
index 6878f8ecc..105fe12fe 100644
--- a/vendor/golang.org/x/net/http2/http2.go
+++ b/vendor/golang.org/x/net/http2/http2.go
@@ -34,7 +34,6 @@ var (
 	VerboseLogs    bool
 	logFrameWrites bool
 	logFrameReads  bool
-	inTests        bool
 
 	// Enabling extended CONNECT by causes browsers to attempt to use
 	// WebSockets-over-HTTP/2. This results in problems when the server's websocket
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index 64085f6e1..bdc5520eb 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -181,6 +181,10 @@ type Server struct {
 type serverInternalState struct {
 	mu          sync.Mutex
 	activeConns map[*serverConn]struct{}
+
+	// Pool of error channels. This is per-Server rather than global
+	// because channels can't be reused across synctest bubbles.
+	errChanPool sync.Pool
 }
 
 func (s *serverInternalState) registerConn(sc *serverConn) {
@@ -212,6 +216,27 @@ func (s *serverInternalState) startGracefulShutdown() {
 	s.mu.Unlock()
 }
 
+// Global error channel pool used for uninitialized Servers.
+// We use a per-Server pool when possible to avoid using channels across synctest bubbles.
+var errChanPool = sync.Pool{
+	New: func() any { return make(chan error, 1) },
+}
+
+func (s *serverInternalState) getErrChan() chan error {
+	if s == nil {
+		return errChanPool.Get().(chan error) // Server used without calling ConfigureServer
+	}
+	return s.errChanPool.Get().(chan error)
+}
+
+func (s *serverInternalState) putErrChan(ch chan error) {
+	if s == nil {
+		errChanPool.Put(ch) // Server used without calling ConfigureServer
+		return
+	}
+	s.errChanPool.Put(ch)
+}
+
 // ConfigureServer adds HTTP/2 support to a net/http Server.
 //
 // The configuration conf may be nil.
@@ -224,7 +249,10 @@ func ConfigureServer(s *http.Server, conf *Server) error {
 	if conf == nil {
 		conf = new(Server)
 	}
-	conf.state = &serverInternalState{activeConns: make(map[*serverConn]struct{})}
+	conf.state = &serverInternalState{
+		activeConns: make(map[*serverConn]struct{}),
+		errChanPool: sync.Pool{New: func() any { return make(chan error, 1) }},
+	}
 	if h1, h2 := s, conf; h2.IdleTimeout == 0 {
 		if h1.IdleTimeout != 0 {
 			h2.IdleTimeout = h1.IdleTimeout
@@ -1124,25 +1152,6 @@ func (sc *serverConn) readPreface() error {
 	}
 }
 
-var errChanPool = sync.Pool{
-	New: func() interface{} { return make(chan error, 1) },
-}
-
-func getErrChan() chan error {
-	if inTests {
-		// Channels cannot be reused across synctest tests.
-		return make(chan error, 1)
-	} else {
-		return errChanPool.Get().(chan error)
-	}
-}
-
-func putErrChan(ch chan error) {
-	if !inTests {
-		errChanPool.Put(ch)
-	}
-}
-
 var writeDataPool = sync.Pool{
 	New: func() interface{} { return new(writeData) },
 }
@@ -1150,7 +1159,7 @@ var writeDataPool = sync.Pool{
 // writeDataFromHandler writes DATA response frames from a handler on
 // the given stream.
 func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStream bool) error {
-	ch := getErrChan()
+	ch := sc.srv.state.getErrChan()
 	writeArg := writeDataPool.Get().(*writeData)
 	*writeArg = writeData{stream.id, data, endStream}
 	err := sc.writeFrameFromHandler(FrameWriteRequest{
@@ -1182,7 +1191,7 @@ func (sc *serverConn) writeDataFromHandler(stream *stream, data []byte, endStrea
 			return errStreamClosed
 		}
 	}
-	putErrChan(ch)
+	sc.srv.state.putErrChan(ch)
 	if frameWriteDone {
 		writeDataPool.Put(writeArg)
 	}
@@ -2436,7 +2445,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro
 		// waiting for this frame to be written, so an http.Flush mid-handler
 		// writes out the correct value of keys, before a handler later potentially
 		// mutates it.
-		errc = getErrChan()
+		errc = sc.srv.state.getErrChan()
 	}
 	if err := sc.writeFrameFromHandler(FrameWriteRequest{
 		write:  headerData,
@@ -2448,7 +2457,7 @@ func (sc *serverConn) writeHeaders(st *stream, headerData *writeResHeaders) erro
 	if errc != nil {
 		select {
 		case err := <-errc:
-			putErrChan(errc)
+			sc.srv.state.putErrChan(errc)
 			return err
 		case <-sc.doneServing:
 			return errClientDisconnected
@@ -3129,7 +3138,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
 		method: opts.Method,
 		url:    u,
 		header: cloneHeader(opts.Header),
-		done:   getErrChan(),
+		done:   sc.srv.state.getErrChan(),
 	}
 
 	select {
@@ -3146,7 +3155,7 @@ func (w *responseWriter) Push(target string, opts *http.PushOptions) error {
 	case <-st.cw:
 		return errStreamClosed
 	case err := <-msg.done:
-		putErrChan(msg.done)
+		sc.srv.state.putErrChan(msg.done)
 		return err
 	}
 }
diff --git a/vendor/golang.org/x/net/http2/transport.go b/vendor/golang.org/x/net/http2/transport.go
index 35e390251..be759b606 100644
--- a/vendor/golang.org/x/net/http2/transport.go
+++ b/vendor/golang.org/x/net/http2/transport.go
@@ -355,6 +355,7 @@ type ClientConn struct {
 	readIdleTimeout             time.Duration
 	pingTimeout                 time.Duration
 	extendedConnectAllowed      bool
+	strictMaxConcurrentStreams  bool
 
 	// rstStreamPingsBlocked works around an unfortunate gRPC behavior.
 	// gRPC strictly limits the number of PING frames that it will receive.
@@ -784,7 +785,8 @@ func (t *Transport) newClientConn(c net.Conn, singleUse bool) (*ClientConn, erro
 		initialWindowSize:           65535,    // spec default
 		initialStreamRecvWindowSize: conf.MaxUploadBufferPerStream,
 		maxConcurrentStreams:        initialMaxConcurrentStreams, // "infinite", per spec. Use a smaller value until we have received server settings.
-		peerMaxHeaderListSize:       0xffffffffffffffff,          // "infinite", per spec. Use 2^64-1 instead.
+		strictMaxConcurrentStreams:  conf.StrictMaxConcurrentRequests,
+		peerMaxHeaderListSize:       0xffffffffffffffff, // "infinite", per spec. Use 2^64-1 instead.
 		streams:                     make(map[uint32]*clientStream),
 		singleUse:                   singleUse,
 		seenSettingsChan:            make(chan struct{}),
@@ -1018,7 +1020,7 @@ func (cc *ClientConn) idleStateLocked() (st clientConnIdleState) {
 		return
 	}
 	var maxConcurrentOkay bool
-	if cc.t.StrictMaxConcurrentStreams {
+	if cc.strictMaxConcurrentStreams {
 		// We'll tell the caller we can take a new request to
 		// prevent the caller from dialing a new TCP
 		// connection, but then we'll block later before
diff --git a/vendor/golang.org/x/net/http2/writesched.go b/vendor/golang.org/x/net/http2/writesched.go
index cc893adc2..4d3890f99 100644
--- a/vendor/golang.org/x/net/http2/writesched.go
+++ b/vendor/golang.org/x/net/http2/writesched.go
@@ -42,6 +42,8 @@ type OpenStreamOptions struct {
 	// PusherID is zero if the stream was initiated by the client. Otherwise,
 	// PusherID names the stream that pushed the newly opened stream.
 	PusherID uint32
+	// priority is used to set the priority of the newly opened stream.
+	priority PriorityParam
 }
 
 // FrameWriteRequest is a request to write a frame.
diff --git a/vendor/golang.org/x/net/http2/writesched_priority.go b/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go
similarity index 78%
rename from vendor/golang.org/x/net/http2/writesched_priority.go
rename to vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go
index f6783339d..6d24d6a1b 100644
--- a/vendor/golang.org/x/net/http2/writesched_priority.go
+++ b/vendor/golang.org/x/net/http2/writesched_priority_rfc7540.go
@@ -11,7 +11,7 @@ import (
 )
 
 // RFC 7540, Section 5.3.5: the default weight is 16.
-const priorityDefaultWeight = 15 // 16 = 15 + 1
+const priorityDefaultWeightRFC7540 = 15 // 16 = 15 + 1
 
 // PriorityWriteSchedulerConfig configures a priorityWriteScheduler.
 type PriorityWriteSchedulerConfig struct {
@@ -66,8 +66,8 @@ func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler
 		}
 	}
 
-	ws := &priorityWriteScheduler{
-		nodes:                make(map[uint32]*priorityNode),
+	ws := &priorityWriteSchedulerRFC7540{
+		nodes:                make(map[uint32]*priorityNodeRFC7540),
 		maxClosedNodesInTree: cfg.MaxClosedNodesInTree,
 		maxIdleNodesInTree:   cfg.MaxIdleNodesInTree,
 		enableWriteThrottle:  cfg.ThrottleOutOfOrderWrites,
@@ -81,32 +81,32 @@ func NewPriorityWriteScheduler(cfg *PriorityWriteSchedulerConfig) WriteScheduler
 	return ws
 }
 
-type priorityNodeState int
+type priorityNodeStateRFC7540 int
 
 const (
-	priorityNodeOpen priorityNodeState = iota
-	priorityNodeClosed
-	priorityNodeIdle
+	priorityNodeOpenRFC7540 priorityNodeStateRFC7540 = iota
+	priorityNodeClosedRFC7540
+	priorityNodeIdleRFC7540
 )
 
-// priorityNode is a node in an HTTP/2 priority tree.
+// priorityNodeRFC7540 is a node in an HTTP/2 priority tree.
 // Each node is associated with a single stream ID.
 // See RFC 7540, Section 5.3.
-type priorityNode struct {
-	q            writeQueue        // queue of pending frames to write
-	id           uint32            // id of the stream, or 0 for the root of the tree
-	weight       uint8             // the actual weight is weight+1, so the value is in [1,256]
-	state        priorityNodeState // open | closed | idle
-	bytes        int64             // number of bytes written by this node, or 0 if closed
-	subtreeBytes int64             // sum(node.bytes) of all nodes in this subtree
+type priorityNodeRFC7540 struct {
+	q            writeQueue               // queue of pending frames to write
+	id           uint32                   // id of the stream, or 0 for the root of the tree
+	weight       uint8                    // the actual weight is weight+1, so the value is in [1,256]
+	state        priorityNodeStateRFC7540 // open | closed | idle
+	bytes        int64                    // number of bytes written by this node, or 0 if closed
+	subtreeBytes int64                    // sum(node.bytes) of all nodes in this subtree
 
 	// These links form the priority tree.
-	parent     *priorityNode
-	kids       *priorityNode // start of the kids list
-	prev, next *priorityNode // doubly-linked list of siblings
+	parent     *priorityNodeRFC7540
+	kids       *priorityNodeRFC7540 // start of the kids list
+	prev, next *priorityNodeRFC7540 // doubly-linked list of siblings
 }
 
-func (n *priorityNode) setParent(parent *priorityNode) {
+func (n *priorityNodeRFC7540) setParent(parent *priorityNodeRFC7540) {
 	if n == parent {
 		panic("setParent to self")
 	}
@@ -141,7 +141,7 @@ func (n *priorityNode) setParent(parent *priorityNode) {
 	}
 }
 
-func (n *priorityNode) addBytes(b int64) {
+func (n *priorityNodeRFC7540) addBytes(b int64) {
 	n.bytes += b
 	for ; n != nil; n = n.parent {
 		n.subtreeBytes += b
@@ -154,7 +154,7 @@ func (n *priorityNode) addBytes(b int64) {
 //
 // f(n, openParent) takes two arguments: the node to visit, n, and a bool that is true
 // if any ancestor p of n is still open (ignoring the root node).
-func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f func(*priorityNode, bool) bool) bool {
+func (n *priorityNodeRFC7540) walkReadyInOrder(openParent bool, tmp *[]*priorityNodeRFC7540, f func(*priorityNodeRFC7540, bool) bool) bool {
 	if !n.q.empty() && f(n, openParent) {
 		return true
 	}
@@ -165,7 +165,7 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f
 	// Don't consider the root "open" when updating openParent since
 	// we can't send data frames on the root stream (only control frames).
 	if n.id != 0 {
-		openParent = openParent || (n.state == priorityNodeOpen)
+		openParent = openParent || (n.state == priorityNodeOpenRFC7540)
 	}
 
 	// Common case: only one kid or all kids have the same weight.
@@ -195,7 +195,7 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f
 		*tmp = append(*tmp, n.kids)
 		n.kids.setParent(nil)
 	}
-	sort.Sort(sortPriorityNodeSiblings(*tmp))
+	sort.Sort(sortPriorityNodeSiblingsRFC7540(*tmp))
 	for i := len(*tmp) - 1; i >= 0; i-- {
 		(*tmp)[i].setParent(n) // setParent inserts at the head of n.kids
 	}
@@ -207,11 +207,11 @@ func (n *priorityNode) walkReadyInOrder(openParent bool, tmp *[]*priorityNode, f
 	return false
 }
 
-type sortPriorityNodeSiblings []*priorityNode
+type sortPriorityNodeSiblingsRFC7540 []*priorityNodeRFC7540
 
-func (z sortPriorityNodeSiblings) Len() int      { return len(z) }
-func (z sortPriorityNodeSiblings) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
-func (z sortPriorityNodeSiblings) Less(i, k int) bool {
+func (z sortPriorityNodeSiblingsRFC7540) Len() int      { return len(z) }
+func (z sortPriorityNodeSiblingsRFC7540) Swap(i, k int) { z[i], z[k] = z[k], z[i] }
+func (z sortPriorityNodeSiblingsRFC7540) Less(i, k int) bool {
 	// Prefer the subtree that has sent fewer bytes relative to its weight.
 	// See sections 5.3.2 and 5.3.4.
 	wi, bi := float64(z[i].weight+1), float64(z[i].subtreeBytes)
@@ -225,13 +225,13 @@ func (z sortPriorityNodeSiblings) Less(i, k int) bool {
 	return bi/bk <= wi/wk
 }
 
-type priorityWriteScheduler struct {
+type priorityWriteSchedulerRFC7540 struct {
 	// root is the root of the priority tree, where root.id = 0.
 	// The root queues control frames that are not associated with any stream.
-	root priorityNode
+	root priorityNodeRFC7540
 
 	// nodes maps stream ids to priority tree nodes.
-	nodes map[uint32]*priorityNode
+	nodes map[uint32]*priorityNodeRFC7540
 
 	// maxID is the maximum stream id in nodes.
 	maxID uint32
@@ -239,7 +239,7 @@ type priorityWriteScheduler struct {
 	// lists of nodes that have been closed or are idle, but are kept in
 	// the tree for improved prioritization. When the lengths exceed either
 	// maxClosedNodesInTree or maxIdleNodesInTree, old nodes are discarded.
-	closedNodes, idleNodes []*priorityNode
+	closedNodes, idleNodes []*priorityNodeRFC7540
 
 	// From the config.
 	maxClosedNodesInTree int
@@ -248,19 +248,19 @@ type priorityWriteScheduler struct {
 	enableWriteThrottle  bool
 
 	// tmp is scratch space for priorityNode.walkReadyInOrder to reduce allocations.
-	tmp []*priorityNode
+	tmp []*priorityNodeRFC7540
 
 	// pool of empty queues for reuse.
 	queuePool writeQueuePool
 }
 
-func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStreamOptions) {
+func (ws *priorityWriteSchedulerRFC7540) OpenStream(streamID uint32, options OpenStreamOptions) {
 	// The stream may be currently idle but cannot be opened or closed.
 	if curr := ws.nodes[streamID]; curr != nil {
-		if curr.state != priorityNodeIdle {
+		if curr.state != priorityNodeIdleRFC7540 {
 			panic(fmt.Sprintf("stream %d already opened", streamID))
 		}
-		curr.state = priorityNodeOpen
+		curr.state = priorityNodeOpenRFC7540
 		return
 	}
 
@@ -272,11 +272,11 @@ func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStream
 	if parent == nil {
 		parent = &ws.root
 	}
-	n := &priorityNode{
+	n := &priorityNodeRFC7540{
 		q:      *ws.queuePool.get(),
 		id:     streamID,
-		weight: priorityDefaultWeight,
-		state:  priorityNodeOpen,
+		weight: priorityDefaultWeightRFC7540,
+		state:  priorityNodeOpenRFC7540,
 	}
 	n.setParent(parent)
 	ws.nodes[streamID] = n
@@ -285,19 +285,19 @@ func (ws *priorityWriteScheduler) OpenStream(streamID uint32, options OpenStream
 	}
 }
 
-func (ws *priorityWriteScheduler) CloseStream(streamID uint32) {
+func (ws *priorityWriteSchedulerRFC7540) CloseStream(streamID uint32) {
 	if streamID == 0 {
 		panic("violation of WriteScheduler interface: cannot close stream 0")
 	}
 	if ws.nodes[streamID] == nil {
 		panic(fmt.Sprintf("violation of WriteScheduler interface: unknown stream %d", streamID))
 	}
-	if ws.nodes[streamID].state != priorityNodeOpen {
+	if ws.nodes[streamID].state != priorityNodeOpenRFC7540 {
 		panic(fmt.Sprintf("violation of WriteScheduler interface: stream %d already closed", streamID))
 	}
 
 	n := ws.nodes[streamID]
-	n.state = priorityNodeClosed
+	n.state = priorityNodeClosedRFC7540
 	n.addBytes(-n.bytes)
 
 	q := n.q
@@ -310,7 +310,7 @@ func (ws *priorityWriteScheduler) CloseStream(streamID uint32) {
 	}
 }
 
-func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority PriorityParam) {
+func (ws *priorityWriteSchedulerRFC7540) AdjustStream(streamID uint32, priority PriorityParam) {
 	if streamID == 0 {
 		panic("adjustPriority on root")
 	}
@@ -324,11 +324,11 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit
 			return
 		}
 		ws.maxID = streamID
-		n = &priorityNode{
+		n = &priorityNodeRFC7540{
 			q:      *ws.queuePool.get(),
 			id:     streamID,
-			weight: priorityDefaultWeight,
-			state:  priorityNodeIdle,
+			weight: priorityDefaultWeightRFC7540,
+			state:  priorityNodeIdleRFC7540,
 		}
 		n.setParent(&ws.root)
 		ws.nodes[streamID] = n
@@ -340,7 +340,7 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit
 	parent := ws.nodes[priority.StreamDep]
 	if parent == nil {
 		n.setParent(&ws.root)
-		n.weight = priorityDefaultWeight
+		n.weight = priorityDefaultWeightRFC7540
 		return
 	}
 
@@ -381,8 +381,8 @@ func (ws *priorityWriteScheduler) AdjustStream(streamID uint32, priority Priorit
 	n.weight = priority.Weight
 }
 
-func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
-	var n *priorityNode
+func (ws *priorityWriteSchedulerRFC7540) Push(wr FrameWriteRequest) {
+	var n *priorityNodeRFC7540
 	if wr.isControl() {
 		n = &ws.root
 	} else {
@@ -401,8 +401,8 @@ func (ws *priorityWriteScheduler) Push(wr FrameWriteRequest) {
 	n.q.push(wr)
 }
 
-func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) {
-	ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNode, openParent bool) bool {
+func (ws *priorityWriteSchedulerRFC7540) Pop() (wr FrameWriteRequest, ok bool) {
+	ws.root.walkReadyInOrder(false, &ws.tmp, func(n *priorityNodeRFC7540, openParent bool) bool {
 		limit := int32(math.MaxInt32)
 		if openParent {
 			limit = ws.writeThrottleLimit
@@ -428,7 +428,7 @@ func (ws *priorityWriteScheduler) Pop() (wr FrameWriteRequest, ok bool) {
 	return wr, ok
 }
 
-func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, maxSize int, n *priorityNode) {
+func (ws *priorityWriteSchedulerRFC7540) addClosedOrIdleNode(list *[]*priorityNodeRFC7540, maxSize int, n *priorityNodeRFC7540) {
 	if maxSize == 0 {
 		return
 	}
@@ -442,7 +442,7 @@ func (ws *priorityWriteScheduler) addClosedOrIdleNode(list *[]*priorityNode, max
 	*list = append(*list, n)
 }
 
-func (ws *priorityWriteScheduler) removeNode(n *priorityNode) {
+func (ws *priorityWriteSchedulerRFC7540) removeNode(n *priorityNodeRFC7540) {
 	for n.kids != nil {
 		n.kids.setParent(n.parent)
 	}
diff --git a/vendor/golang.org/x/net/http2/writesched_priority_rfc9128.go b/vendor/golang.org/x/net/http2/writesched_priority_rfc9128.go
new file mode 100644
index 000000000..9b5b8808e
--- /dev/null
+++ b/vendor/golang.org/x/net/http2/writesched_priority_rfc9128.go
@@ -0,0 +1,209 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http2
+
+import (
+	"fmt"
+	"math"
+)
+
+type streamMetadata struct {
+	location *writeQueue
+	priority PriorityParam
+}
+
+type priorityWriteSchedulerRFC9218 struct {
+	// control contains control frames (SETTINGS, PING, etc.).
+	control writeQueue
+
+	// heads contain the head of a circular list of streams.
+	// We put these heads within a nested array that represents urgency and
+	// incremental, as defined in
+	// https://www.rfc-editor.org/rfc/rfc9218.html#name-priority-parameters.
+	// 8 represents u=0 up to u=7, and 2 represents i=false and i=true.
+	heads [8][2]*writeQueue
+
+	// streams contains a mapping between each stream ID and their metadata, so
+	// we can quickly locate them when needing to, for example, adjust their
+	// priority.
+	streams map[uint32]streamMetadata
+
+	// queuePool are empty queues for reuse.
+	queuePool writeQueuePool
+
+	// prioritizeIncremental is used to determine whether we should prioritize
+	// incremental streams or not, when urgency is the same in a given Pop()
+	// call.
+	prioritizeIncremental bool
+}
+
+func newPriorityWriteSchedulerRFC9128() WriteScheduler {
+	ws := &priorityWriteSchedulerRFC9218{
+		streams: make(map[uint32]streamMetadata),
+	}
+	return ws
+}
+
+func (ws *priorityWriteSchedulerRFC9218) OpenStream(streamID uint32, opt OpenStreamOptions) {
+	if ws.streams[streamID].location != nil {
+		panic(fmt.Errorf("stream %d already opened", streamID))
+	}
+	q := ws.queuePool.get()
+	ws.streams[streamID] = streamMetadata{
+		location: q,
+		priority: opt.priority,
+	}
+
+	u, i := opt.priority.urgency, opt.priority.incremental
+	if ws.heads[u][i] == nil {
+		ws.heads[u][i] = q
+		q.next = q
+		q.prev = q
+	} else {
+		// Queues are stored in a ring.
+		// Insert the new stream before ws.head, putting it at the end of the list.
+		q.prev = ws.heads[u][i].prev
+		q.next = ws.heads[u][i]
+		q.prev.next = q
+		q.next.prev = q
+	}
+}
+
+func (ws *priorityWriteSchedulerRFC9218) CloseStream(streamID uint32) {
+	metadata := ws.streams[streamID]
+	q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental
+	if q == nil {
+		return
+	}
+	if q.next == q {
+		// This was the only open stream.
+		ws.heads[u][i] = nil
+	} else {
+		q.prev.next = q.next
+		q.next.prev = q.prev
+		if ws.heads[u][i] == q {
+			ws.heads[u][i] = q.next
+		}
+	}
+	delete(ws.streams, streamID)
+	ws.queuePool.put(q)
+}
+
+func (ws *priorityWriteSchedulerRFC9218) AdjustStream(streamID uint32, priority PriorityParam) {
+	metadata := ws.streams[streamID]
+	q, u, i := metadata.location, metadata.priority.urgency, metadata.priority.incremental
+	if q == nil {
+		return
+	}
+
+	// Remove stream from current location.
+	if q.next == q {
+		// This was the only open stream.
+		ws.heads[u][i] = nil
+	} else {
+		q.prev.next = q.next
+		q.next.prev = q.prev
+		if ws.heads[u][i] == q {
+			ws.heads[u][i] = q.next
+		}
+	}
+
+	// Insert stream to the new queue.
+	u, i = priority.urgency, priority.incremental
+	if ws.heads[u][i] == nil {
+		ws.heads[u][i] = q
+		q.next = q
+		q.prev = q
+	} else {
+		// Queues are stored in a ring.
+		// Insert the new stream before ws.head, putting it at the end of the list.
+		q.prev = ws.heads[u][i].prev
+		q.next = ws.heads[u][i]
+		q.prev.next = q
+		q.next.prev = q
+	}
+
+	// Update the metadata.
+	ws.streams[streamID] = streamMetadata{
+		location: q,
+		priority: priority,
+	}
+}
+
+func (ws *priorityWriteSchedulerRFC9218) Push(wr FrameWriteRequest) {
+	if wr.isControl() {
+		ws.control.push(wr)
+		return
+	}
+	q := ws.streams[wr.StreamID()].location
+	if q == nil {
+		// This is a closed stream.
+		// wr should not be a HEADERS or DATA frame.
+		// We push the request onto the control queue.
+		if wr.DataSize() > 0 {
+			panic("add DATA on non-open stream")
+		}
+		ws.control.push(wr)
+		return
+	}
+	q.push(wr)
+}
+
+func (ws *priorityWriteSchedulerRFC9218) Pop() (FrameWriteRequest, bool) {
+	// Control and RST_STREAM frames first.
+	if !ws.control.empty() {
+		return ws.control.shift(), true
+	}
+
+	// On the next Pop(), we want to prioritize incremental if we prioritized
+	// non-incremental request of the same urgency this time. Vice-versa.
+	// i.e. when there are incremental and non-incremental requests at the same
+	// priority, we give 50% of our bandwidth to the incremental ones in
+	// aggregate and 50% to the first non-incremental one (since
+	// non-incremental streams do not use round-robin writes).
+	ws.prioritizeIncremental = !ws.prioritizeIncremental
+
+	// Always prioritize lowest u (i.e. highest urgency level).
+	for u := range ws.heads {
+		for i := range ws.heads[u] {
+			// When we want to prioritize incremental, we try to pop i=true
+			// first before i=false when u is the same.
+			if ws.prioritizeIncremental {
+				i = (i + 1) % 2
+			}
+			q := ws.heads[u][i]
+			if q == nil {
+				continue
+			}
+			for {
+				if wr, ok := q.consume(math.MaxInt32); ok {
+					if i == 1 {
+						// For incremental streams, we update head to q.next so
+						// we can round-robin between multiple streams that can
+						// immediately benefit from partial writes.
+						ws.heads[u][i] = q.next
+					} else {
+						// For non-incremental streams, we try to finish one to
+						// completion rather than doing round-robin. However,
+						// we update head here so that if q.consume() is !ok
+						// (e.g. the stream has no more frame to consume), head
+						// is updated to the next q that has frames to consume
+						// on future iterations. This way, we do not prioritize
+						// writing to unavailable stream on next Pop() calls,
+						// preventing head-of-line blocking.
+						ws.heads[u][i] = q
+					}
+					return wr, true
+				}
+				q = q.next
+				if q == ws.heads[u][i] {
+					break
+				}
+			}
+
+		}
+	}
+	return FrameWriteRequest{}, false
+}
diff --git a/vendor/golang.org/x/net/http2/writesched_roundrobin.go b/vendor/golang.org/x/net/http2/writesched_roundrobin.go
index 54fe86322..737cff9ec 100644
--- a/vendor/golang.org/x/net/http2/writesched_roundrobin.go
+++ b/vendor/golang.org/x/net/http2/writesched_roundrobin.go
@@ -25,7 +25,7 @@ type roundRobinWriteScheduler struct {
 }
 
 // newRoundRobinWriteScheduler constructs a new write scheduler.
-// The round robin scheduler priorizes control frames
+// The round robin scheduler prioritizes control frames
 // like SETTINGS and PING over DATA frames.
 // When there are no control frames to send, it performs a round-robin
 // selection from the ready streams.
diff --git a/vendor/golang.org/x/net/internal/httpcommon/request.go b/vendor/golang.org/x/net/internal/httpcommon/request.go
index 4b7055317..1e10f89eb 100644
--- a/vendor/golang.org/x/net/internal/httpcommon/request.go
+++ b/vendor/golang.org/x/net/internal/httpcommon/request.go
@@ -51,7 +51,7 @@ type EncodeHeadersParam struct {
 	DefaultUserAgent string
 }
 
-// EncodeHeadersParam is the result of EncodeHeaders.
+// EncodeHeadersResult is the result of EncodeHeaders.
 type EncodeHeadersResult struct {
 	HasBody     bool
 	HasTrailers bool
@@ -399,7 +399,7 @@ type ServerRequestResult struct {
 
 	// If the request should be rejected, this is a short string suitable for passing
 	// to the http2 package's CountError function.
-	// It might be a bit odd to return errors this way rather than returing an error,
+	// It might be a bit odd to return errors this way rather than returning an error,
 	// but this ensures we don't forget to include a CountError reason.
 	InvalidReason string
 }
diff --git a/vendor/golang.org/x/net/internal/socks/socks.go b/vendor/golang.org/x/net/internal/socks/socks.go
index 84fcc32b6..8eedb84ce 100644
--- a/vendor/golang.org/x/net/internal/socks/socks.go
+++ b/vendor/golang.org/x/net/internal/socks/socks.go
@@ -297,7 +297,7 @@ func (up *UsernamePassword) Authenticate(ctx context.Context, rw io.ReadWriter,
 		b = append(b, up.Username...)
 		b = append(b, byte(len(up.Password)))
 		b = append(b, up.Password...)
-		// TODO(mikio): handle IO deadlines and cancelation if
+		// TODO(mikio): handle IO deadlines and cancellation if
 		// necessary
 		if _, err := rw.Write(b); err != nil {
 			return err
diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go
index 1d8cffae8..2f45dbc86 100644
--- a/vendor/golang.org/x/sync/errgroup/errgroup.go
+++ b/vendor/golang.org/x/sync/errgroup/errgroup.go
@@ -3,7 +3,7 @@
 // license that can be found in the LICENSE file.
 
 // Package errgroup provides synchronization, error propagation, and Context
-// cancelation for groups of goroutines working on subtasks of a common task.
+// cancellation for groups of goroutines working on subtasks of a common task.
 //
 // [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks
 // returning errors.
diff --git a/vendor/golang.org/x/sys/unix/affinity_linux.go b/vendor/golang.org/x/sys/unix/affinity_linux.go
index 3c7a6d6e2..3ea470387 100644
--- a/vendor/golang.org/x/sys/unix/affinity_linux.go
+++ b/vendor/golang.org/x/sys/unix/affinity_linux.go
@@ -41,6 +41,15 @@ func (s *CPUSet) Zero() {
 	clear(s[:])
 }
 
+// Fill adds all possible CPU bits to the set s. On Linux, [SchedSetaffinity]
+// will silently ignore any invalid CPU bits in [CPUSet] so this is an
+// efficient way of resetting the CPU affinity of a process.
+func (s *CPUSet) Fill() {
+	for i := range s {
+		s[i] = ^cpuMask(0)
+	}
+}
+
 func cpuBitsIndex(cpu int) int {
 	return cpu / _NCPUBITS
 }
diff --git a/vendor/golang.org/x/sys/unix/fdset.go b/vendor/golang.org/x/sys/unix/fdset.go
index 9e83d18cd..62ed12645 100644
--- a/vendor/golang.org/x/sys/unix/fdset.go
+++ b/vendor/golang.org/x/sys/unix/fdset.go
@@ -23,7 +23,5 @@ func (fds *FdSet) IsSet(fd int) bool {
 
 // Zero clears the set fds.
 func (fds *FdSet) Zero() {
-	for i := range fds.Bits {
-		fds.Bits[i] = 0
-	}
+	clear(fds.Bits[:])
 }
diff --git a/vendor/golang.org/x/sys/unix/ifreq_linux.go b/vendor/golang.org/x/sys/unix/ifreq_linux.go
index 848840ae4..309f5a2b0 100644
--- a/vendor/golang.org/x/sys/unix/ifreq_linux.go
+++ b/vendor/golang.org/x/sys/unix/ifreq_linux.go
@@ -111,9 +111,7 @@ func (ifr *Ifreq) SetUint32(v uint32) {
 // clear zeroes the ifreq's union field to prevent trailing garbage data from
 // being sent to the kernel if an ifreq is reused.
 func (ifr *Ifreq) clear() {
-	for i := range ifr.raw.Ifru {
-		ifr.raw.Ifru[i] = 0
-	}
+	clear(ifr.raw.Ifru[:])
 }
 
 // TODO(mdlayher): export as IfreqData? For now we can provide helpers such as
diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh
index e6f31d374..d0ed61191 100644
--- a/vendor/golang.org/x/sys/unix/mkall.sh
+++ b/vendor/golang.org/x/sys/unix/mkall.sh
@@ -49,6 +49,7 @@ esac
 if [[ "$GOOS" = "linux" ]]; then
 	# Use the Docker-based build system
 	# Files generated through docker (use $cmd so you can Ctl-C the build or run)
+	set -e
 	$cmd docker build --tag generate:$GOOS $GOOS
 	$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS
 	exit
diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go
index 4958a6570..9439af961 100644
--- a/vendor/golang.org/x/sys/unix/syscall_linux.go
+++ b/vendor/golang.org/x/sys/unix/syscall_linux.go
@@ -801,9 +801,7 @@ func (sa *SockaddrPPPoE) sockaddr() (unsafe.Pointer, _Socklen, error) {
 	// one. The kernel expects SID to be in network byte order.
 	binary.BigEndian.PutUint16(sa.raw[6:8], sa.SID)
 	copy(sa.raw[8:14], sa.Remote)
-	for i := 14; i < 14+IFNAMSIZ; i++ {
-		sa.raw[i] = 0
-	}
+	clear(sa.raw[14 : 14+IFNAMSIZ])
 	copy(sa.raw[14:], sa.Dev)
 	return unsafe.Pointer(&sa.raw), SizeofSockaddrPPPoX, nil
 }
diff --git a/vendor/golang.org/x/sys/unix/syscall_netbsd.go b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
index 88162099a..34a467697 100644
--- a/vendor/golang.org/x/sys/unix/syscall_netbsd.go
+++ b/vendor/golang.org/x/sys/unix/syscall_netbsd.go
@@ -248,6 +248,23 @@ func Statvfs(path string, buf *Statvfs_t) (err error) {
 	return Statvfs1(path, buf, ST_WAIT)
 }
 
+func Getvfsstat(buf []Statvfs_t, flags int) (n int, err error) {
+	var (
+		_p0     unsafe.Pointer
+		bufsize uintptr
+	)
+	if len(buf) > 0 {
+		_p0 = unsafe.Pointer(&buf[0])
+		bufsize = unsafe.Sizeof(Statvfs_t{}) * uintptr(len(buf))
+	}
+	r0, _, e1 := Syscall(SYS_GETVFSSTAT, uintptr(_p0), bufsize, uintptr(flags))
+	n = int(r0)
+	if e1 != 0 {
+		err = e1
+	}
+	return
+}
+
 /*
  * Exposed directly
  */
diff --git a/vendor/golang.org/x/sys/windows/syscall_windows.go b/vendor/golang.org/x/sys/windows/syscall_windows.go
index 640f6b153..bd5133730 100644
--- a/vendor/golang.org/x/sys/windows/syscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/syscall_windows.go
@@ -321,6 +321,8 @@ func NewCallbackCDecl(fn interface{}) uintptr {
 //sys	SetConsoleOutputCP(cp uint32) (err error) = kernel32.SetConsoleOutputCP
 //sys	WriteConsole(console Handle, buf *uint16, towrite uint32, written *uint32, reserved *byte) (err error) = kernel32.WriteConsoleW
 //sys	ReadConsole(console Handle, buf *uint16, toread uint32, read *uint32, inputControl *byte) (err error) = kernel32.ReadConsoleW
+//sys	GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) = kernel32.GetNumberOfConsoleInputEvents
+//sys	FlushConsoleInputBuffer(console Handle) (err error) = kernel32.FlushConsoleInputBuffer
 //sys	resizePseudoConsole(pconsole Handle, size uint32) (hr error) = kernel32.ResizePseudoConsole
 //sys	CreateToolhelp32Snapshot(flags uint32, processId uint32) (handle Handle, err error) [failretval==InvalidHandle] = kernel32.CreateToolhelp32Snapshot
 //sys	Module32First(snapshot Handle, moduleEntry *ModuleEntry32) (err error) = kernel32.Module32FirstW
diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go
index 993a2297d..358be3c7f 100644
--- a/vendor/golang.org/x/sys/windows/types_windows.go
+++ b/vendor/golang.org/x/sys/windows/types_windows.go
@@ -65,6 +65,22 @@ var signals = [...]string{
 	15: "terminated",
 }
 
+// File flags for [os.OpenFile]. The O_ prefix is used to indicate
+// that these flags are specific to the OpenFile function.
+const (
+	O_FILE_FLAG_OPEN_NO_RECALL     = FILE_FLAG_OPEN_NO_RECALL
+	O_FILE_FLAG_OPEN_REPARSE_POINT = FILE_FLAG_OPEN_REPARSE_POINT
+	O_FILE_FLAG_SESSION_AWARE      = FILE_FLAG_SESSION_AWARE
+	O_FILE_FLAG_POSIX_SEMANTICS    = FILE_FLAG_POSIX_SEMANTICS
+	O_FILE_FLAG_BACKUP_SEMANTICS   = FILE_FLAG_BACKUP_SEMANTICS
+	O_FILE_FLAG_DELETE_ON_CLOSE    = FILE_FLAG_DELETE_ON_CLOSE
+	O_FILE_FLAG_SEQUENTIAL_SCAN    = FILE_FLAG_SEQUENTIAL_SCAN
+	O_FILE_FLAG_RANDOM_ACCESS      = FILE_FLAG_RANDOM_ACCESS
+	O_FILE_FLAG_NO_BUFFERING       = FILE_FLAG_NO_BUFFERING
+	O_FILE_FLAG_OVERLAPPED         = FILE_FLAG_OVERLAPPED
+	O_FILE_FLAG_WRITE_THROUGH      = FILE_FLAG_WRITE_THROUGH
+)
+
 const (
 	FILE_READ_DATA        = 0x00000001
 	FILE_READ_ATTRIBUTES  = 0x00000080
diff --git a/vendor/golang.org/x/sys/windows/zsyscall_windows.go b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
index 641a5f4b7..426151a01 100644
--- a/vendor/golang.org/x/sys/windows/zsyscall_windows.go
+++ b/vendor/golang.org/x/sys/windows/zsyscall_windows.go
@@ -238,6 +238,7 @@ var (
 	procFindResourceW                                        = modkernel32.NewProc("FindResourceW")
 	procFindVolumeClose                                      = modkernel32.NewProc("FindVolumeClose")
 	procFindVolumeMountPointClose                            = modkernel32.NewProc("FindVolumeMountPointClose")
+	procFlushConsoleInputBuffer                              = modkernel32.NewProc("FlushConsoleInputBuffer")
 	procFlushFileBuffers                                     = modkernel32.NewProc("FlushFileBuffers")
 	procFlushViewOfFile                                      = modkernel32.NewProc("FlushViewOfFile")
 	procFormatMessageW                                       = modkernel32.NewProc("FormatMessageW")
@@ -284,6 +285,7 @@ var (
 	procGetNamedPipeHandleStateW                             = modkernel32.NewProc("GetNamedPipeHandleStateW")
 	procGetNamedPipeInfo                                     = modkernel32.NewProc("GetNamedPipeInfo")
 	procGetNamedPipeServerProcessId                          = modkernel32.NewProc("GetNamedPipeServerProcessId")
+	procGetNumberOfConsoleInputEvents                        = modkernel32.NewProc("GetNumberOfConsoleInputEvents")
 	procGetOverlappedResult                                  = modkernel32.NewProc("GetOverlappedResult")
 	procGetPriorityClass                                     = modkernel32.NewProc("GetPriorityClass")
 	procGetProcAddress                                       = modkernel32.NewProc("GetProcAddress")
@@ -2111,6 +2113,14 @@ func FindVolumeMountPointClose(findVolumeMountPoint Handle) (err error) {
 	return
 }
 
+func FlushConsoleInputBuffer(console Handle) (err error) {
+	r1, _, e1 := syscall.SyscallN(procFlushConsoleInputBuffer.Addr(), uintptr(console))
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func FlushFileBuffers(handle Handle) (err error) {
 	r1, _, e1 := syscall.SyscallN(procFlushFileBuffers.Addr(), uintptr(handle))
 	if r1 == 0 {
@@ -2481,6 +2491,14 @@ func GetNamedPipeServerProcessId(pipe Handle, serverProcessID *uint32) (err erro
 	return
 }
 
+func GetNumberOfConsoleInputEvents(console Handle, numevents *uint32) (err error) {
+	r1, _, e1 := syscall.SyscallN(procGetNumberOfConsoleInputEvents.Addr(), uintptr(console), uintptr(unsafe.Pointer(numevents)))
+	if r1 == 0 {
+		err = errnoErr(e1)
+	}
+	return
+}
+
 func GetOverlappedResult(handle Handle, overlapped *Overlapped, done *uint32, wait bool) (err error) {
 	var _p0 uint32
 	if wait {
diff --git a/vendor/golang.org/x/text/unicode/bidi/core.go b/vendor/golang.org/x/text/unicode/bidi/core.go
index 9d2ae547b..fb8273236 100644
--- a/vendor/golang.org/x/text/unicode/bidi/core.go
+++ b/vendor/golang.org/x/text/unicode/bidi/core.go
@@ -427,13 +427,6 @@ type isolatingRunSequence struct {
 
 func (i *isolatingRunSequence) Len() int { return len(i.indexes) }
 
-func maxLevel(a, b level) level {
-	if a > b {
-		return a
-	}
-	return b
-}
-
 // Rule X10, second bullet: Determine the start-of-sequence (sos) and end-of-sequence (eos) types,
 // either L or R, for each isolating run sequence.
 func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence {
@@ -474,8 +467,8 @@ func (p *paragraph) isolatingRunSequence(indexes []int) *isolatingRunSequence {
 		indexes: indexes,
 		types:   types,
 		level:   level,
-		sos:     typeForLevel(maxLevel(prevLevel, level)),
-		eos:     typeForLevel(maxLevel(succLevel, level)),
+		sos:     typeForLevel(max(prevLevel, level)),
+		eos:     typeForLevel(max(succLevel, level)),
 	}
 }
 
diff --git a/vendor/golang.org/x/time/rate/rate.go b/vendor/golang.org/x/time/rate/rate.go
index 794b2e32b..563270c15 100644
--- a/vendor/golang.org/x/time/rate/rate.go
+++ b/vendor/golang.org/x/time/rate/rate.go
@@ -195,7 +195,7 @@ func (r *Reservation) CancelAt(t time.Time) {
 	// update state
 	r.lim.last = t
 	r.lim.tokens = tokens
-	if r.timeToAct == r.lim.lastEvent {
+	if r.timeToAct.Equal(r.lim.lastEvent) {
 		prevEvent := r.timeToAct.Add(r.limit.durationFromTokens(float64(-r.tokens)))
 		if !prevEvent.Before(t) {
 			r.lim.lastEvent = prevEvent
diff --git a/vendor/golang.org/x/tools/go/ast/astutil/imports.go b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
index 5e5601aa4..5bacc0fa4 100644
--- a/vendor/golang.org/x/tools/go/ast/astutil/imports.go
+++ b/vendor/golang.org/x/tools/go/ast/astutil/imports.go
@@ -209,48 +209,46 @@ func DeleteImport(fset *token.FileSet, f *ast.File, path string) (deleted bool)
 // DeleteNamedImport deletes the import with the given name and path from the file f, if present.
 // If there are duplicate import declarations, all matching ones are deleted.
 func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (deleted bool) {
-	var delspecs []*ast.ImportSpec
-	var delcomments []*ast.CommentGroup
+	var (
+		delspecs    = make(map[*ast.ImportSpec]bool)
+		delcomments = make(map[*ast.CommentGroup]bool)
+	)
 
 	// Find the import nodes that import path, if any.
 	for i := 0; i < len(f.Decls); i++ {
-		decl := f.Decls[i]
-		gen, ok := decl.(*ast.GenDecl)
+		gen, ok := f.Decls[i].(*ast.GenDecl)
 		if !ok || gen.Tok != token.IMPORT {
 			continue
 		}
 		for j := 0; j < len(gen.Specs); j++ {
-			spec := gen.Specs[j]
-			impspec := spec.(*ast.ImportSpec)
+			impspec := gen.Specs[j].(*ast.ImportSpec)
 			if importName(impspec) != name || importPath(impspec) != path {
 				continue
 			}
 
 			// We found an import spec that imports path.
 			// Delete it.
-			delspecs = append(delspecs, impspec)
+			delspecs[impspec] = true
 			deleted = true
-			copy(gen.Specs[j:], gen.Specs[j+1:])
-			gen.Specs = gen.Specs[:len(gen.Specs)-1]
+			gen.Specs = slices.Delete(gen.Specs, j, j+1)
 
 			// If this was the last import spec in this decl,
 			// delete the decl, too.
 			if len(gen.Specs) == 0 {
-				copy(f.Decls[i:], f.Decls[i+1:])
-				f.Decls = f.Decls[:len(f.Decls)-1]
+				f.Decls = slices.Delete(f.Decls, i, i+1)
 				i--
 				break
 			} else if len(gen.Specs) == 1 {
 				if impspec.Doc != nil {
-					delcomments = append(delcomments, impspec.Doc)
+					delcomments[impspec.Doc] = true
 				}
 				if impspec.Comment != nil {
-					delcomments = append(delcomments, impspec.Comment)
+					delcomments[impspec.Comment] = true
 				}
 				for _, cg := range f.Comments {
 					// Found comment on the same line as the import spec.
 					if cg.End() < impspec.Pos() && fset.Position(cg.End()).Line == fset.Position(impspec.Pos()).Line {
-						delcomments = append(delcomments, cg)
+						delcomments[cg] = true
 						break
 					}
 				}
@@ -294,38 +292,21 @@ func DeleteNamedImport(fset *token.FileSet, f *ast.File, name, path string) (del
 	}
 
 	// Delete imports from f.Imports.
-	for i := 0; i < len(f.Imports); i++ {
-		imp := f.Imports[i]
-		for j, del := range delspecs {
-			if imp == del {
-				copy(f.Imports[i:], f.Imports[i+1:])
-				f.Imports = f.Imports[:len(f.Imports)-1]
-				copy(delspecs[j:], delspecs[j+1:])
-				delspecs = delspecs[:len(delspecs)-1]
-				i--
-				break
-			}
-		}
+	before := len(f.Imports)
+	f.Imports = slices.DeleteFunc(f.Imports, func(imp *ast.ImportSpec) bool {
+		_, ok := delspecs[imp]
+		return ok
+	})
+	if len(f.Imports)+len(delspecs) != before {
+		// This can happen when the AST is invalid (i.e. imports differ between f.Decls and f.Imports).
+		panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
 	}
 
 	// Delete comments from f.Comments.
-	for i := 0; i < len(f.Comments); i++ {
-		cg := f.Comments[i]
-		for j, del := range delcomments {
-			if cg == del {
-				copy(f.Comments[i:], f.Comments[i+1:])
-				f.Comments = f.Comments[:len(f.Comments)-1]
-				copy(delcomments[j:], delcomments[j+1:])
-				delcomments = delcomments[:len(delcomments)-1]
-				i--
-				break
-			}
-		}
-	}
-
-	if len(delspecs) > 0 {
-		panic(fmt.Sprintf("deleted specs from Decls but not Imports: %v", delspecs))
-	}
+	f.Comments = slices.DeleteFunc(f.Comments, func(cg *ast.CommentGroup) bool {
+		_, ok := delcomments[cg]
+		return ok
+	})
 
 	return
 }
diff --git a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go
index 31c8d2f24..7e72d3c28 100644
--- a/vendor/golang.org/x/tools/go/ast/inspector/cursor.go
+++ b/vendor/golang.org/x/tools/go/ast/inspector/cursor.go
@@ -40,7 +40,7 @@ type Cursor struct {
 // Root returns a cursor for the virtual root node,
 // whose children are the files provided to [New].
 //
-// Its [Cursor.Node] and [Cursor.Stack] methods return nil.
+// Its [Cursor.Node] method return nil.
 func (in *Inspector) Root() Cursor {
 	return Cursor{in, -1}
 }
diff --git a/vendor/golang.org/x/tools/go/packages/golist.go b/vendor/golang.org/x/tools/go/packages/golist.go
index 89f89dd2d..680a70ca8 100644
--- a/vendor/golang.org/x/tools/go/packages/golist.go
+++ b/vendor/golang.org/x/tools/go/packages/golist.go
@@ -364,12 +364,6 @@ type jsonPackage struct {
 	DepsErrors []*packagesinternal.PackageError
 }
 
-type jsonPackageError struct {
-	ImportStack []string
-	Pos         string
-	Err         string
-}
-
 func otherFiles(p *jsonPackage) [][]string {
 	return [][]string{p.CFiles, p.CXXFiles, p.MFiles, p.HFiles, p.FFiles, p.SFiles, p.SwigFiles, p.SwigCXXFiles, p.SysoFiles}
 }
diff --git a/vendor/golang.org/x/tools/go/packages/visit.go b/vendor/golang.org/x/tools/go/packages/visit.go
index df14ffd94..af6a60d75 100644
--- a/vendor/golang.org/x/tools/go/packages/visit.go
+++ b/vendor/golang.org/x/tools/go/packages/visit.go
@@ -5,9 +5,11 @@
 package packages
 
 import (
+	"cmp"
 	"fmt"
+	"iter"
 	"os"
-	"sort"
+	"slices"
 )
 
 // Visit visits all the packages in the import graph whose roots are
@@ -16,6 +18,20 @@ import (
 // package's dependencies have been visited (postorder).
 // The boolean result of pre(pkg) determines whether
 // the imports of package pkg are visited.
+//
+// Example:
+//
+//	pkgs, err := Load(...)
+//	if err != nil { ... }
+//	Visit(pkgs, nil, func(pkg *Package) {
+//		log.Println(pkg)
+//	})
+//
+// In most cases, it is more convenient to use [Postorder]:
+//
+//	for pkg := range Postorder(pkgs) {
+//		log.Println(pkg)
+//	}
 func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
 	seen := make(map[*Package]bool)
 	var visit func(*Package)
@@ -24,13 +40,8 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
 			seen[pkg] = true
 
 			if pre == nil || pre(pkg) {
-				paths := make([]string, 0, len(pkg.Imports))
-				for path := range pkg.Imports {
-					paths = append(paths, path)
-				}
-				sort.Strings(paths) // Imports is a map, this makes visit stable
-				for _, path := range paths {
-					visit(pkg.Imports[path])
+				for _, imp := range sorted(pkg.Imports) { // for determinism
+					visit(imp)
 				}
 			}
 
@@ -50,7 +61,7 @@ func Visit(pkgs []*Package, pre func(*Package) bool, post func(*Package)) {
 func PrintErrors(pkgs []*Package) int {
 	var n int
 	errModules := make(map[*Module]bool)
-	Visit(pkgs, nil, func(pkg *Package) {
+	for pkg := range Postorder(pkgs) {
 		for _, err := range pkg.Errors {
 			fmt.Fprintln(os.Stderr, err)
 			n++
@@ -63,6 +74,60 @@ func PrintErrors(pkgs []*Package) int {
 			fmt.Fprintln(os.Stderr, mod.Error.Err)
 			n++
 		}
-	})
+	}
 	return n
 }
+
+// Postorder returns an iterator over the the packages in
+// the import graph whose roots are pkg.
+// Packages are enumerated in dependencies-first order.
+func Postorder(pkgs []*Package) iter.Seq[*Package] {
+	return func(yield func(*Package) bool) {
+		seen := make(map[*Package]bool)
+		var visit func(*Package) bool
+		visit = func(pkg *Package) bool {
+			if !seen[pkg] {
+				seen[pkg] = true
+				for _, imp := range sorted(pkg.Imports) { // for determinism
+					if !visit(imp) {
+						return false
+					}
+				}
+				if !yield(pkg) {
+					return false
+				}
+			}
+			return true
+		}
+		for _, pkg := range pkgs {
+			if !visit(pkg) {
+				break
+			}
+		}
+	}
+}
+
+// -- copied from golang.org.x/tools/gopls/internal/util/moremaps --
+
+// sorted returns an iterator over the entries of m in key order.
+func sorted[M ~map[K]V, K cmp.Ordered, V any](m M) iter.Seq2[K, V] {
+	// TODO(adonovan): use maps.Sorted if proposal #68598 is accepted.
+	return func(yield func(K, V) bool) {
+		keys := keySlice(m)
+		slices.Sort(keys)
+		for _, k := range keys {
+			if !yield(k, m[k]) {
+				break
+			}
+		}
+	}
+}
+
+// KeySlice returns the keys of the map M, like slices.Collect(maps.Keys(m)).
+func keySlice[M ~map[K]V, K comparable, V any](m M) []K {
+	r := make([]K, 0, len(m))
+	for k := range m {
+		r = append(r, k)
+	}
+	return r
+}
diff --git a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
index d3c2913be..6c0c74968 100644
--- a/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
+++ b/vendor/golang.org/x/tools/go/types/objectpath/objectpath.go
@@ -698,7 +698,10 @@ func Object(pkg *types.Package, p Path) (types.Object, error) {
 			} else if false && aliases.Enabled() {
 				// The Enabled check is too expensive, so for now we
 				// simply assume that aliases are not enabled.
-				// TODO(adonovan): replace with "if true {" when go1.24 is assured.
+				//
+				// Now that go1.24 is assured, we should be able to
+				// replace this with "if true {", but it causes tests
+				// to fail. TODO(adonovan): investigate.
 				return nil, fmt.Errorf("cannot apply %q to %s (got %T, want alias)", code, t, t)
 			}
 
diff --git a/vendor/golang.org/x/tools/go/types/typeutil/map.go b/vendor/golang.org/x/tools/go/types/typeutil/map.go
index b6d542c64..f035a0b6b 100644
--- a/vendor/golang.org/x/tools/go/types/typeutil/map.go
+++ b/vendor/golang.org/x/tools/go/types/typeutil/map.go
@@ -11,7 +11,6 @@ import (
 	"fmt"
 	"go/types"
 	"hash/maphash"
-	"unsafe"
 
 	"golang.org/x/tools/internal/typeparams"
 )
@@ -380,22 +379,8 @@ var theSeed = maphash.MakeSeed()
 func (hasher) hashTypeName(tname *types.TypeName) uint32 {
 	// Since types.Identical uses == to compare TypeNames,
 	// the Hash function uses maphash.Comparable.
-	// TODO(adonovan): or will, when it becomes available in go1.24.
-	// In the meantime we use the pointer's numeric value.
-	//
-	//   hash := maphash.Comparable(theSeed, tname)
-	//
-	// (Another approach would be to hash the name and package
-	// path, and whether or not it is a package-level typename. It
-	// is rare for a package to define multiple local types with
-	// the same name.)
-	ptr := uintptr(unsafe.Pointer(tname))
-	if unsafe.Sizeof(ptr) == 8 {
-		hash := uint64(ptr)
-		return uint32(hash ^ (hash >> 32))
-	} else {
-		return uint32(ptr)
-	}
+	hash := maphash.Comparable(theSeed, tname)
+	return uint32(hash ^ (hash >> 32))
 }
 
 // shallowHash computes a hash of t without looking at any of its
diff --git a/vendor/golang.org/x/tools/imports/forward.go b/vendor/golang.org/x/tools/imports/forward.go
index cb6db8893..22ae77772 100644
--- a/vendor/golang.org/x/tools/imports/forward.go
+++ b/vendor/golang.org/x/tools/imports/forward.go
@@ -69,9 +69,3 @@ func Process(filename string, src []byte, opt *Options) ([]byte, error) {
 	}
 	return intimp.Process(filename, src, intopt)
 }
-
-// VendorlessPath returns the devendorized version of the import path ipath.
-// For example, VendorlessPath("foo/bar/vendor/a/b") returns "a/b".
-func VendorlessPath(ipath string) string {
-	return intimp.VendorlessPath(ipath)
-}
diff --git a/vendor/golang.org/x/tools/internal/event/core/event.go b/vendor/golang.org/x/tools/internal/event/core/event.go
index a6cf0e64a..ade5d1e79 100644
--- a/vendor/golang.org/x/tools/internal/event/core/event.go
+++ b/vendor/golang.org/x/tools/internal/event/core/event.go
@@ -28,11 +28,6 @@ type Event struct {
 	dynamic []label.Label  // dynamically sized storage for remaining labels
 }
 
-// eventLabelMap implements label.Map for a the labels of an Event.
-type eventLabelMap struct {
-	event Event
-}
-
 func (ev Event) At() time.Time { return ev.at }
 
 func (ev Event) Format(f fmt.State, r rune) {
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
index 780873e3a..4a4357d2b 100644
--- a/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
+++ b/vendor/golang.org/x/tools/internal/gcimporter/iexport.go
@@ -569,7 +569,6 @@ func (p *iexporter) exportName(obj types.Object) (res string) {
 
 type iexporter struct {
 	fset    *token.FileSet
-	out     *bytes.Buffer
 	version int
 
 	shallow    bool                // don't put types from other packages in the index
diff --git a/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go b/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go
deleted file mode 100644
index 7586bfaca..000000000
--- a/vendor/golang.org/x/tools/internal/gcimporter/iimport_go122.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2024 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-//go:build go1.22 && !go1.24
-
-package gcimporter
-
-import (
-	"go/token"
-	"go/types"
-	"unsafe"
-)
-
-// TODO(rfindley): delete this workaround once go1.24 is assured.
-
-func init() {
-	// Update markBlack so that it correctly sets the color
-	// of imported TypeNames.
-	//
-	// See the doc comment for markBlack for details.
-
-	type color uint32
-	const (
-		white color = iota
-		black
-		grey
-	)
-	type object struct {
-		_      *types.Scope
-		_      token.Pos
-		_      *types.Package
-		_      string
-		_      types.Type
-		_      uint32
-		color_ color
-		_      token.Pos
-	}
-	type typeName struct {
-		object
-	}
-
-	// If the size of types.TypeName changes, this will fail to compile.
-	const delta = int64(unsafe.Sizeof(typeName{})) - int64(unsafe.Sizeof(types.TypeName{}))
-	var _ [-delta * delta]int
-
-	markBlack = func(obj *types.TypeName) {
-		type uP = unsafe.Pointer
-		var ptr *typeName
-		*(*uP)(uP(&ptr)) = uP(obj)
-		ptr.color_ = black
-	}
-}
diff --git a/vendor/golang.org/x/tools/internal/imports/fix.go b/vendor/golang.org/x/tools/internal/imports/fix.go
index 50b6ca51a..1b4dc0cb5 100644
--- a/vendor/golang.org/x/tools/internal/imports/fix.go
+++ b/vendor/golang.org/x/tools/internal/imports/fix.go
@@ -16,6 +16,7 @@ import (
 	"go/types"
 	"io/fs"
 	"io/ioutil"
+	"maps"
 	"os"
 	"path"
 	"path/filepath"
@@ -27,8 +28,6 @@ import (
 	"unicode"
 	"unicode/utf8"
 
-	"maps"
-
 	"golang.org/x/tools/go/ast/astutil"
 	"golang.org/x/tools/internal/event"
 	"golang.org/x/tools/internal/gocommand"
@@ -43,7 +42,7 @@ var importToGroup = []func(localPrefix, importPath string) (num int, ok bool){
 		if localPrefix == "" {
 			return
 		}
-		for _, p := range strings.Split(localPrefix, ",") {
+		for p := range strings.SplitSeq(localPrefix, ",") {
 			if strings.HasPrefix(importPath, p) || strings.TrimSuffix(p, "/") == importPath {
 				return 3, true
 			}
@@ -1251,7 +1250,6 @@ func ImportPathToAssumedName(importPath string) string {
 // gopathResolver implements resolver for GOPATH workspaces.
 type gopathResolver struct {
 	env      *ProcessEnv
-	walked   bool
 	cache    *DirInfoCache
 	scanSema chan struct{} // scanSema prevents concurrent scans.
 }
diff --git a/vendor/golang.org/x/tools/internal/modindex/symbols.go b/vendor/golang.org/x/tools/internal/modindex/symbols.go
index fe24db9b1..8e9702d84 100644
--- a/vendor/golang.org/x/tools/internal/modindex/symbols.go
+++ b/vendor/golang.org/x/tools/internal/modindex/symbols.go
@@ -206,8 +206,7 @@ func isDeprecated(doc *ast.CommentGroup) bool {
 	// go.dev/wiki/Deprecated Paragraph starting 'Deprecated:'
 	// This code fails for /* Deprecated: */, but it's the code from
 	// gopls/internal/analysis/deprecated
-	lines := strings.Split(doc.Text(), "\n\n")
-	for _, line := range lines {
+	for line := range strings.SplitSeq(doc.Text(), "\n\n") {
 		if strings.HasPrefix(line, "Deprecated:") {
 			return true
 		}
diff --git a/vendor/golang.org/x/tools/internal/stdlib/deps.go b/vendor/golang.org/x/tools/internal/stdlib/deps.go
index 77cf8d218..96ad6c582 100644
--- a/vendor/golang.org/x/tools/internal/stdlib/deps.go
+++ b/vendor/golang.org/x/tools/internal/stdlib/deps.go
@@ -12,348 +12,354 @@ type pkginfo struct {
 }
 
 var deps = [...]pkginfo{
-	{"archive/tar", "\x03j\x03E5\x01\v\x01#\x01\x01\x02\x05\n\x02\x01\x02\x02\v"},
-	{"archive/zip", "\x02\x04`\a\x16\x0205\x01+\x05\x01\x11\x03\x02\r\x04"},
-	{"bufio", "\x03j}F\x13"},
-	{"bytes", "m+R\x03\fH\x02\x02"},
+	{"archive/tar", "\x03k\x03E;\x01\n\x01$\x01\x01\x02\x05\b\x02\x01\x02\x02\f"},
+	{"archive/zip", "\x02\x04a\a\x03\x12\x021;\x01+\x05\x01\x0f\x03\x02\x0e\x04"},
+	{"bufio", "\x03k\x83\x01D\x14"},
+	{"bytes", "n*Y\x03\fG\x02\x02"},
 	{"cmp", ""},
-	{"compress/bzip2", "\x02\x02\xe6\x01C"},
-	{"compress/flate", "\x02k\x03z\r\x025\x01\x03"},
-	{"compress/gzip", "\x02\x04`\a\x03\x15eU"},
-	{"compress/lzw", "\x02k\x03z"},
-	{"compress/zlib", "\x02\x04`\a\x03\x13\x01f"},
-	{"container/heap", "\xae\x02"},
+	{"compress/bzip2", "\x02\x02\xed\x01A"},
+	{"compress/flate", "\x02l\x03\x80\x01\f\x033\x01\x03"},
+	{"compress/gzip", "\x02\x04a\a\x03\x14lT"},
+	{"compress/lzw", "\x02l\x03\x80\x01"},
+	{"compress/zlib", "\x02\x04a\a\x03\x12\x01m"},
+	{"container/heap", "\xb3\x02"},
 	{"container/list", ""},
 	{"container/ring", ""},
-	{"context", "m\\i\x01\f"},
-	{"crypto", "\x83\x01gE"},
-	{"crypto/aes", "\x10\n\a\x8e\x02"},
-	{"crypto/cipher", "\x03\x1e\x01\x01\x1d\x11\x1c,Q"},
-	{"crypto/des", "\x10\x13\x1d-,\x96\x01\x03"},
-	{"crypto/dsa", "@\x04)}\x0e"},
-	{"crypto/ecdh", "\x03\v\f\x0e\x04\x14\x04\r\x1c}"},
-	{"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\x16\x01\x04\f\x01\x1c}\x0e\x04L\x01"},
-	{"crypto/ed25519", "\x0e\x1c\x16\n\a\x1c}E"},
-	{"crypto/elliptic", "0=}\x0e:"},
-	{"crypto/fips140", " \x05\x90\x01"},
-	{"crypto/hkdf", "-\x12\x01-\x16"},
-	{"crypto/hmac", "\x1a\x14\x11\x01\x112"},
+	{"context", "n\\m\x01\r"},
+	{"crypto", "\x83\x01nC"},
+	{"crypto/aes", "\x10\n\a\x93\x02"},
+	{"crypto/cipher", "\x03\x1e\x01\x01\x1e\x11\x1c+X"},
+	{"crypto/des", "\x10\x13\x1e-+\x9b\x01\x03"},
+	{"crypto/dsa", "A\x04)\x83\x01\r"},
+	{"crypto/ecdh", "\x03\v\f\x0e\x04\x15\x04\r\x1c\x83\x01"},
+	{"crypto/ecdsa", "\x0e\x05\x03\x04\x01\x0e\a\v\x05\x01\x04\f\x01\x1c\x83\x01\r\x05K\x01"},
+	{"crypto/ed25519", "\x0e\x1c\x11\x06\n\a\x1c\x83\x01C"},
+	{"crypto/elliptic", "0>\x83\x01\r9"},
+	{"crypto/fips140", " \x05"},
+	{"crypto/hkdf", "-\x13\x01-\x15"},
+	{"crypto/hmac", "\x1a\x14\x12\x01\x111"},
 	{"crypto/internal/boring", "\x0e\x02\rf"},
-	{"crypto/internal/boring/bbig", "\x1a\xde\x01M"},
-	{"crypto/internal/boring/bcache", "\xb3\x02\x12"},
+	{"crypto/internal/boring/bbig", "\x1a\xe4\x01M"},
+	{"crypto/internal/boring/bcache", "\xb8\x02\x13"},
 	{"crypto/internal/boring/sig", ""},
-	{"crypto/internal/cryptotest", "\x03\r\n)\x0e\x19\x06\x13\x12#\a\t\x11\x11\x11\x1b\x01\f\r\x05\n"},
-	{"crypto/internal/entropy", "E"},
-	{"crypto/internal/fips140", ">/}9\r\x15"},
-	{"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x04\x01\x01\x05*\x8c\x016"},
-	{"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x04\x01\x06*\x8a\x01"},
-	{"crypto/internal/fips140/alias", "\xc5\x02"},
-	{"crypto/internal/fips140/bigmod", "%\x17\x01\x06*\x8c\x01"},
-	{"crypto/internal/fips140/check", " \x0e\x06\b\x02\xac\x01["},
-	{"crypto/internal/fips140/check/checktest", "%\xfe\x01\""},
-	{"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x04\b\x01(}\x0f9"},
-	{"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\f1}\x0f9"},
-	{"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x067}H"},
-	{"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v7\xc2\x01\x03"},
-	{"crypto/internal/fips140/edwards25519", "%\a\f\x041\x8c\x019"},
-	{"crypto/internal/fips140/edwards25519/field", "%\x13\x041\x8c\x01"},
-	{"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x069"},
-	{"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x017"},
-	{"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x041"},
-	{"crypto/internal/fips140/nistec", "%\f\a\x041\x8c\x01*\x0f\x13"},
-	{"crypto/internal/fips140/nistec/fiat", "%\x135\x8c\x01"},
-	{"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x069"},
-	{"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x025}H"},
-	{"crypto/internal/fips140/sha256", "\x03\x1d\x1c\x01\x06*\x8c\x01"},
-	{"crypto/internal/fips140/sha3", "\x03\x1d\x18\x04\x010\x8c\x01L"},
-	{"crypto/internal/fips140/sha512", "\x03\x1d\x1c\x01\x06*\x8c\x01"},
-	{"crypto/internal/fips140/ssh", " \x05"},
-	{"crypto/internal/fips140/subtle", "#"},
-	{"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x027"},
-	{"crypto/internal/fips140/tls13", "\x03\x1d\x05\b\a\b1"},
+	{"crypto/internal/cryptotest", "\x03\r\n\x06$\x0e\x19\x06\x12\x12 \x04\a\t\x16\x01\x11\x11\x1b\x01\a\x05\b\x03\x05\v"},
+	{"crypto/internal/entropy", "F"},
+	{"crypto/internal/fips140", "?/\x15\xa7\x01\v\x16"},
+	{"crypto/internal/fips140/aes", "\x03\x1d\x03\x02\x13\x05\x01\x01\x05*\x92\x014"},
+	{"crypto/internal/fips140/aes/gcm", " \x01\x02\x02\x02\x11\x05\x01\x06*\x8f\x01"},
+	{"crypto/internal/fips140/alias", "\xcb\x02"},
+	{"crypto/internal/fips140/bigmod", "%\x18\x01\x06*\x92\x01"},
+	{"crypto/internal/fips140/check", " \x0e\x06\t\x02\xb2\x01Z"},
+	{"crypto/internal/fips140/check/checktest", "%\x85\x02!"},
+	{"crypto/internal/fips140/drbg", "\x03\x1c\x01\x01\x04\x13\x05\b\x01(\x83\x01\x0f7"},
+	{"crypto/internal/fips140/ecdh", "\x03\x1d\x05\x02\t\r1\x83\x01\x0f7"},
+	{"crypto/internal/fips140/ecdsa", "\x03\x1d\x04\x01\x02\a\x02\x068\x15nF"},
+	{"crypto/internal/fips140/ed25519", "\x03\x1d\x05\x02\x04\v8\xc6\x01\x03"},
+	{"crypto/internal/fips140/edwards25519", "%\a\f\x051\x92\x017"},
+	{"crypto/internal/fips140/edwards25519/field", "%\x13\x051\x92\x01"},
+	{"crypto/internal/fips140/hkdf", "\x03\x1d\x05\t\x06:\x15"},
+	{"crypto/internal/fips140/hmac", "\x03\x1d\x14\x01\x018\x15"},
+	{"crypto/internal/fips140/mlkem", "\x03\x1d\x05\x02\x0e\x03\x051"},
+	{"crypto/internal/fips140/nistec", "%\f\a\x051\x92\x01*\r\x14"},
+	{"crypto/internal/fips140/nistec/fiat", "%\x136\x92\x01"},
+	{"crypto/internal/fips140/pbkdf2", "\x03\x1d\x05\t\x06:\x15"},
+	{"crypto/internal/fips140/rsa", "\x03\x1d\x04\x01\x02\r\x01\x01\x026\x15nF"},
+	{"crypto/internal/fips140/sha256", "\x03\x1d\x1d\x01\x06*\x15}"},
+	{"crypto/internal/fips140/sha3", "\x03\x1d\x18\x05\x010\x92\x01K"},
+	{"crypto/internal/fips140/sha512", "\x03\x1d\x1d\x01\x06*\x15}"},
+	{"crypto/internal/fips140/ssh", "%^"},
+	{"crypto/internal/fips140/subtle", "#\x1a\xc3\x01"},
+	{"crypto/internal/fips140/tls12", "\x03\x1d\x05\t\x06\x028\x15"},
+	{"crypto/internal/fips140/tls13", "\x03\x1d\x05\b\a\t1\x15"},
+	{"crypto/internal/fips140cache", "\xaa\x02\r&"},
 	{"crypto/internal/fips140deps", ""},
 	{"crypto/internal/fips140deps/byteorder", "\x99\x01"},
-	{"crypto/internal/fips140deps/cpu", "\xad\x01\a"},
-	{"crypto/internal/fips140deps/godebug", "\xb5\x01"},
-	{"crypto/internal/fips140hash", "5\x1a4\xc2\x01"},
-	{"crypto/internal/fips140only", "'\r\x01\x01M25"},
+	{"crypto/internal/fips140deps/cpu", "\xae\x01\a"},
+	{"crypto/internal/fips140deps/godebug", "\xb6\x01"},
+	{"crypto/internal/fips140hash", "5\x1b3\xc8\x01"},
+	{"crypto/internal/fips140only", "'\r\x01\x01M3;"},
 	{"crypto/internal/fips140test", ""},
-	{"crypto/internal/hpke", "\x0e\x01\x01\x03\x1a\x1d#,`N"},
-	{"crypto/internal/impl", "\xb0\x02"},
-	{"crypto/internal/randutil", "\xea\x01\x12"},
-	{"crypto/internal/sysrand", "mi!\x1f\r\x0f\x01\x01\v\x06"},
-	{"crypto/internal/sysrand/internal/seccomp", "m"},
-	{"crypto/md5", "\x0e2-\x16\x16`"},
+	{"crypto/internal/hpke", "\x0e\x01\x01\x03\x053#+gM"},
+	{"crypto/internal/impl", "\xb5\x02"},
+	{"crypto/internal/randutil", "\xf1\x01\x12"},
+	{"crypto/internal/sysrand", "nn! \r\r\x01\x01\f\x06"},
+	{"crypto/internal/sysrand/internal/seccomp", "n"},
+	{"crypto/md5", "\x0e3-\x15\x16g"},
 	{"crypto/mlkem", "/"},
-	{"crypto/pbkdf2", "2\r\x01-\x16"},
-	{"crypto/rand", "\x1a\x06\a\x19\x04\x01(}\x0eM"},
-	{"crypto/rc4", "#\x1d-\xc2\x01"},
-	{"crypto/rsa", "\x0e\f\x01\t\x0f\f\x01\x04\x06\a\x1c\x03\x1325\r\x01"},
-	{"crypto/sha1", "\x0e\f&-\x16\x16\x14L"},
+	{"crypto/pbkdf2", "2\x0e\x01-\x15"},
+	{"crypto/rand", "\x1a\x06\a\x1a\x04\x01(\x83\x01\rM"},
+	{"crypto/rc4", "#\x1e-\xc6\x01"},
+	{"crypto/rsa", "\x0e\f\x01\t\x0f\r\x01\x04\x06\a\x1c\x03\x123;\f\x01"},
+	{"crypto/sha1", "\x0e\f'\x03*\x15\x16\x15R"},
 	{"crypto/sha256", "\x0e\f\x1aO"},
-	{"crypto/sha3", "\x0e'N\xc2\x01"},
+	{"crypto/sha3", "\x0e'N\xc8\x01"},
 	{"crypto/sha512", "\x0e\f\x1cM"},
-	{"crypto/subtle", "8\x96\x01U"},
-	{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x03\x01\a\x01\v\x02\n\x01\b\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x13\x16\x14\b5\x16\x16\r\n\x01\x01\x01\x02\x01\f\x06\x02\x01"},
-	{"crypto/tls/internal/fips140tls", " \x93\x02"},
-	{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x011\x03\x02\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x032\x01\x02\t\x01\x01\x01\a\x10\x05\x01\x06\x02\x05\f\x01\x02\r\x02\x01\x01\x02\x03\x01"},
-	{"crypto/x509/pkix", "c\x06\a\x88\x01G"},
-	{"database/sql", "\x03\nJ\x16\x03z\f\x06\"\x05\n\x02\x03\x01\f\x02\x02\x02"},
-	{"database/sql/driver", "\r`\x03\xae\x01\x11\x10"},
-	{"debug/buildinfo", "\x03W\x02\x01\x01\b\a\x03`\x18\x02\x01+\x0f "},
-	{"debug/dwarf", "\x03c\a\x03z1\x13\x01\x01"},
-	{"debug/elf", "\x03\x06P\r\a\x03`\x19\x01,\x19\x01\x15"},
-	{"debug/gosym", "\x03c\n\xbe\x01\x01\x01\x02"},
-	{"debug/macho", "\x03\x06P\r\n`\x1a,\x19\x01"},
-	{"debug/pe", "\x03\x06P\r\a\x03`\x1a,\x19\x01\x15"},
-	{"debug/plan9obj", "f\a\x03`\x1a,"},
-	{"embed", "m+:\x18\x01T"},
+	{"crypto/subtle", "8\x9b\x01W"},
+	{"crypto/tls", "\x03\b\x02\x01\x01\x01\x01\x02\x01\x01\x01\x02\x01\x01\a\x01\r\n\x01\t\x05\x03\x01\x01\x01\x01\x02\x01\x02\x01\x17\x02\x03\x12\x16\x15\b;\x16\x16\r\b\x01\x01\x01\x02\x01\r\x06\x02\x01\x0f"},
+	{"crypto/tls/internal/fips140tls", "\x17\xa1\x02"},
+	{"crypto/x509", "\x03\v\x01\x01\x01\x01\x01\x01\x01\x012\x05\x01\x01\x02\x05\x0e\x06\x02\x02\x03E\x038\x01\x02\b\x01\x01\x02\a\x10\x05\x01\x06\x02\x05\n\x01\x02\x0e\x02\x01\x01\x02\x03\x01"},
+	{"crypto/x509/pkix", "d\x06\a\x8d\x01G"},
+	{"database/sql", "\x03\nK\x16\x03\x80\x01\v\a\"\x05\b\x02\x03\x01\r\x02\x02\x02"},
+	{"database/sql/driver", "\ra\x03\xb4\x01\x0f\x11"},
+	{"debug/buildinfo", "\x03X\x02\x01\x01\b\a\x03e\x19\x02\x01+\x0f\x1f"},
+	{"debug/dwarf", "\x03d\a\x03\x80\x011\x11\x01\x01"},
+	{"debug/elf", "\x03\x06Q\r\a\x03e\x1a\x01,\x17\x01\x16"},
+	{"debug/gosym", "\x03d\n\xc2\x01\x01\x01\x02"},
+	{"debug/macho", "\x03\x06Q\r\ne\x1b,\x17\x01"},
+	{"debug/pe", "\x03\x06Q\r\a\x03e\x1b,\x17\x01\x16"},
+	{"debug/plan9obj", "g\a\x03e\x1b,"},
+	{"embed", "n*@\x19\x01S"},
 	{"embed/internal/embedtest", ""},
 	{"encoding", ""},
-	{"encoding/ascii85", "\xea\x01E"},
-	{"encoding/asn1", "\x03j\x03\x87\x01\x01&\x0f\x02\x01\x0f\x03\x01"},
-	{"encoding/base32", "\xea\x01C\x02"},
-	{"encoding/base64", "\x99\x01QC\x02"},
-	{"encoding/binary", "m}\r'\x0f\x05"},
-	{"encoding/csv", "\x02\x01j\x03zF\x11\x02"},
-	{"encoding/gob", "\x02_\x05\a\x03`\x1a\f\x01\x02\x1d\b\x14\x01\x0e\x02"},
-	{"encoding/hex", "m\x03zC\x03"},
-	{"encoding/json", "\x03\x01]\x04\b\x03z\r'\x0f\x02\x01\x02\x0f\x01\x01\x02"},
-	{"encoding/pem", "\x03b\b}C\x03"},
-	{"encoding/xml", "\x02\x01^\f\x03z4\x05\f\x01\x02\x0f\x02"},
-	{"errors", "\xc9\x01|"},
-	{"expvar", "jK9\t\n\x15\r\n\x02\x03\x01\x10"},
-	{"flag", "a\f\x03z,\b\x05\n\x02\x01\x0f"},
-	{"fmt", "mE8\r\x1f\b\x0f\x02\x03\x11"},
-	{"go/ast", "\x03\x01l\x0f\x01j\x03)\b\x0f\x02\x01"},
-	{"go/ast/internal/tests", ""},
-	{"go/build", "\x02\x01j\x03\x01\x03\x02\a\x02\x01\x17\x1e\x04\x02\t\x14\x12\x01+\x01\x04\x01\a\n\x02\x01\x11\x02\x02"},
-	{"go/build/constraint", "m\xc2\x01\x01\x11\x02"},
-	{"go/constant", "p\x10w\x01\x016\x01\x02\x11"},
-	{"go/doc", "\x04l\x01\x06\t=-1\x12\x02\x01\x11\x02"},
-	{"go/doc/comment", "\x03m\xbd\x01\x01\x01\x01\x11\x02"},
-	{"go/format", "\x03m\x01\f\x01\x02jF"},
-	{"go/importer", "s\a\x01\x01\x04\x01i9"},
-	{"go/internal/gccgoimporter", "\x02\x01W\x13\x03\x05\v\x01g\x02,\x01\x05\x13\x01\v\b"},
-	{"go/internal/gcimporter", "\x02n\x10\x01/\x05\x0e',\x17\x03\x02"},
-	{"go/internal/srcimporter", "p\x01\x02\n\x03\x01i,\x01\x05\x14\x02\x13"},
-	{"go/parser", "\x03j\x03\x01\x03\v\x01j\x01+\x06\x14"},
-	{"go/printer", "p\x01\x03\x03\tj\r\x1f\x17\x02\x01\x02\n\x05\x02"},
-	{"go/scanner", "\x03m\x10j2\x12\x01\x12\x02"},
-	{"go/token", "\x04l\xbd\x01\x02\x03\x01\x0e\x02"},
-	{"go/types", "\x03\x01\x06c\x03\x01\x04\b\x03\x02\x15\x1e\x06+\x04\x03\n%\a\n\x01\x01\x01\x02\x01\x0e\x02\x02"},
-	{"go/version", "\xba\x01v"},
-	{"hash", "\xea\x01"},
-	{"hash/adler32", "m\x16\x16"},
-	{"hash/crc32", "m\x16\x16\x14\x85\x01\x01\x12"},
-	{"hash/crc64", "m\x16\x16\x99\x01"},
-	{"hash/fnv", "m\x16\x16`"},
-	{"hash/maphash", "\x94\x01\x05\x1b\x03@N"},
-	{"html", "\xb0\x02\x02\x11"},
-	{"html/template", "\x03g\x06\x19,5\x01\v \x05\x01\x02\x03\x0e\x01\x02\v\x01\x03\x02"},
-	{"image", "\x02k\x1f^\x0f6\x03\x01"},
+	{"encoding/ascii85", "\xf1\x01C"},
+	{"encoding/asn1", "\x03k\x03\x8c\x01\x01'\r\x02\x01\x10\x03\x01"},
+	{"encoding/base32", "\xf1\x01A\x02"},
+	{"encoding/base64", "\x99\x01XA\x02"},
+	{"encoding/binary", "n\x83\x01\f(\r\x05"},
+	{"encoding/csv", "\x02\x01k\x03\x80\x01D\x12\x02"},
+	{"encoding/gob", "\x02`\x05\a\x03e\x1b\v\x01\x03\x1d\b\x12\x01\x0f\x02"},
+	{"encoding/hex", "n\x03\x80\x01A\x03"},
+	{"encoding/json", "\x03\x01^\x04\b\x03\x80\x01\f(\r\x02\x01\x02\x10\x01\x01\x02"},
+	{"encoding/pem", "\x03c\b\x83\x01A\x03"},
+	{"encoding/xml", "\x02\x01_\f\x03\x80\x014\x05\n\x01\x02\x10\x02"},
+	{"errors", "\xca\x01\x81\x01"},
+	{"expvar", "kK?\b\v\x15\r\b\x02\x03\x01\x11"},
+	{"flag", "b\f\x03\x80\x01,\b\x05\b\x02\x01\x10"},
+	{"fmt", "nE>\f \b\r\x02\x03\x12"},
+	{"go/ast", "\x03\x01m\x0e\x01q\x03)\b\r\x02\x01"},
+	{"go/build", "\x02\x01k\x03\x01\x02\x02\a\x02\x01\x17\x1f\x04\x02\t\x19\x13\x01+\x01\x04\x01\a\b\x02\x01\x12\x02\x02"},
+	{"go/build/constraint", "n\xc6\x01\x01\x12\x02"},
+	{"go/constant", "q\x0f}\x01\x024\x01\x02\x12"},
+	{"go/doc", "\x04m\x01\x05\t>31\x10\x02\x01\x12\x02"},
+	{"go/doc/comment", "\x03n\xc1\x01\x01\x01\x01\x12\x02"},
+	{"go/format", "\x03n\x01\v\x01\x02qD"},
+	{"go/importer", "s\a\x01\x01\x04\x01p9"},
+	{"go/internal/gccgoimporter", "\x02\x01X\x13\x03\x04\v\x01n\x02,\x01\x05\x11\x01\f\b"},
+	{"go/internal/gcimporter", "\x02o\x0f\x010\x05\x0e-,\x15\x03\x02"},
+	{"go/internal/srcimporter", "q\x01\x01\n\x03\x01p,\x01\x05\x12\x02\x14"},
+	{"go/parser", "\x03k\x03\x01\x02\v\x01q\x01+\x06\x12"},
+	{"go/printer", "q\x01\x02\x03\tq\f \x15\x02\x01\x02\v\x05\x02"},
+	{"go/scanner", "\x03n\x0fq2\x10\x01\x13\x02"},
+	{"go/token", "\x04m\x83\x01>\x02\x03\x01\x0f\x02"},
+	{"go/types", "\x03\x01\x06d\x03\x01\x03\b\x03\x02\x15\x1f\x061\x04\x03\t \x06\a\b\x01\x01\x01\x02\x01\x0f\x02\x02"},
+	{"go/version", "\xbb\x01z"},
+	{"hash", "\xf1\x01"},
+	{"hash/adler32", "n\x15\x16"},
+	{"hash/crc32", "n\x15\x16\x15\x89\x01\x01\x13"},
+	{"hash/crc64", "n\x15\x16\x9e\x01"},
+	{"hash/fnv", "n\x15\x16g"},
+	{"hash/maphash", "\x83\x01\x11!\x03\x93\x01"},
+	{"html", "\xb5\x02\x02\x12"},
+	{"html/template", "\x03h\x06\x18-;\x01\n!\x05\x01\x02\x03\f\x01\x02\f\x01\x03\x02"},
+	{"image", "\x02l\x1ee\x0f4\x03\x01"},
 	{"image/color", ""},
 	{"image/color/palette", "\x8c\x01"},
 	{"image/draw", "\x8b\x01\x01\x04"},
-	{"image/gif", "\x02\x01\x05e\x03\x1b\x01\x01\x01\vQ"},
+	{"image/gif", "\x02\x01\x05f\x03\x1a\x01\x01\x01\vX"},
 	{"image/internal/imageutil", "\x8b\x01"},
-	{"image/jpeg", "\x02k\x1e\x01\x04Z"},
-	{"image/png", "\x02\a]\n\x13\x02\x06\x01^E"},
-	{"index/suffixarray", "\x03c\a}\r*\f\x01"},
-	{"internal/abi", "\xb4\x01\x91\x01"},
-	{"internal/asan", "\xc5\x02"},
-	{"internal/bisect", "\xa3\x02\x0f\x01"},
-	{"internal/buildcfg", "pG_\x06\x02\x05\f\x01"},
-	{"internal/bytealg", "\xad\x01\x98\x01"},
+	{"image/jpeg", "\x02l\x1d\x01\x04a"},
+	{"image/png", "\x02\a^\n\x12\x02\x06\x01eC"},
+	{"index/suffixarray", "\x03d\a\x83\x01\f+\n\x01"},
+	{"internal/abi", "\xb5\x01\x96\x01"},
+	{"internal/asan", "\xcb\x02"},
+	{"internal/bisect", "\xaa\x02\r\x01"},
+	{"internal/buildcfg", "qGe\x06\x02\x05\n\x01"},
+	{"internal/bytealg", "\xae\x01\x9d\x01"},
 	{"internal/byteorder", ""},
 	{"internal/cfg", ""},
-	{"internal/chacha8rand", "\x99\x01\x1b\x91\x01"},
+	{"internal/cgrouptest", "q[Q\x06\x0f\x02\x01\x04\x01"},
+	{"internal/chacha8rand", "\x99\x01\x15\a\x96\x01"},
 	{"internal/copyright", ""},
 	{"internal/coverage", ""},
 	{"internal/coverage/calloc", ""},
-	{"internal/coverage/cfile", "j\x06\x17\x16\x01\x02\x01\x01\x01\x01\x01\x01\x01#\x01\x1f,\x06\a\f\x01\x03\f\x06"},
-	{"internal/coverage/cformat", "\x04l-\x04I\f7\x01\x02\f"},
-	{"internal/coverage/cmerge", "p-Z"},
-	{"internal/coverage/decodecounter", "f\n-\v\x02@,\x19\x16"},
-	{"internal/coverage/decodemeta", "\x02d\n\x17\x16\v\x02@,"},
-	{"internal/coverage/encodecounter", "\x02d\n-\f\x01\x02>\f \x17"},
-	{"internal/coverage/encodemeta", "\x02\x01c\n\x13\x04\x16\r\x02>,/"},
-	{"internal/coverage/pods", "\x04l-y\x06\x05\f\x02\x01"},
-	{"internal/coverage/rtcov", "\xc5\x02"},
-	{"internal/coverage/slicereader", "f\nz["},
-	{"internal/coverage/slicewriter", "pz"},
-	{"internal/coverage/stringtab", "p8\x04>"},
+	{"internal/coverage/cfile", "k\x06\x16\x17\x01\x02\x01\x01\x01\x01\x01\x01\x01#\x02$,\x06\a\n\x01\x03\r\x06"},
+	{"internal/coverage/cformat", "\x04m-\x04O\v6\x01\x02\r"},
+	{"internal/coverage/cmerge", "q-_"},
+	{"internal/coverage/decodecounter", "g\n-\v\x02F,\x17\x17"},
+	{"internal/coverage/decodemeta", "\x02e\n\x16\x17\v\x02F,"},
+	{"internal/coverage/encodecounter", "\x02e\n-\f\x01\x02D\v!\x15"},
+	{"internal/coverage/encodemeta", "\x02\x01d\n\x12\x04\x17\r\x02D,."},
+	{"internal/coverage/pods", "\x04m-\x7f\x06\x05\n\x02\x01"},
+	{"internal/coverage/rtcov", "\xcb\x02"},
+	{"internal/coverage/slicereader", "g\n\x80\x01Z"},
+	{"internal/coverage/slicewriter", "q\x80\x01"},
+	{"internal/coverage/stringtab", "q8\x04D"},
 	{"internal/coverage/test", ""},
 	{"internal/coverage/uleb128", ""},
-	{"internal/cpu", "\xc5\x02"},
-	{"internal/dag", "\x04l\xbd\x01\x03"},
-	{"internal/diff", "\x03m\xbe\x01\x02"},
-	{"internal/exportdata", "\x02\x01j\x03\x03]\x1a,\x01\x05\x13\x01\x02"},
-	{"internal/filepathlite", "m+:\x19B"},
-	{"internal/fmtsort", "\x04\x9a\x02\x0f"},
-	{"internal/fuzz", "\x03\nA\x18\x04\x03\x03\x01\f\x0355\r\x02\x1d\x01\x05\x02\x05\f\x01\x02\x01\x01\v\x04\x02"},
+	{"internal/cpu", "\xcb\x02"},
+	{"internal/dag", "\x04m\xc1\x01\x03"},
+	{"internal/diff", "\x03n\xc2\x01\x02"},
+	{"internal/exportdata", "\x02\x01k\x03\x02c\x1b,\x01\x05\x11\x01\x02"},
+	{"internal/filepathlite", "n*@\x1a@"},
+	{"internal/fmtsort", "\x04\xa1\x02\r"},
+	{"internal/fuzz", "\x03\nB\x18\x04\x03\x03\x01\v\x036;\f\x03\x1d\x01\x05\x02\x05\n\x01\x02\x01\x01\f\x04\x02"},
 	{"internal/goarch", ""},
-	{"internal/godebug", "\x96\x01 |\x01\x12"},
+	{"internal/godebug", "\x96\x01!\x80\x01\x01\x13"},
 	{"internal/godebugs", ""},
 	{"internal/goexperiment", ""},
 	{"internal/goos", ""},
-	{"internal/goroot", "\x96\x02\x01\x05\x14\x02"},
+	{"internal/goroot", "\x9d\x02\x01\x05\x12\x02"},
 	{"internal/gover", "\x04"},
 	{"internal/goversion", ""},
 	{"internal/itoa", ""},
-	{"internal/lazyregexp", "\x96\x02\v\x0f\x02"},
-	{"internal/lazytemplate", "\xea\x01,\x1a\x02\v"},
-	{"internal/msan", "\xc5\x02"},
+	{"internal/lazyregexp", "\x9d\x02\v\r\x02"},
+	{"internal/lazytemplate", "\xf1\x01,\x18\x02\f"},
+	{"internal/msan", "\xcb\x02"},
 	{"internal/nettrace", ""},
-	{"internal/obscuretestdata", "e\x85\x01,"},
-	{"internal/oserror", "m"},
-	{"internal/pkgbits", "\x03K\x18\a\x03\x05\vj\x0e\x1e\r\f\x01"},
+	{"internal/obscuretestdata", "f\x8b\x01,"},
+	{"internal/oserror", "n"},
+	{"internal/pkgbits", "\x03L\x18\a\x03\x04\vq\r\x1f\r\n\x01"},
 	{"internal/platform", ""},
-	{"internal/poll", "mO\x1a\x149\x0f\x01\x01\v\x06"},
-	{"internal/profile", "\x03\x04f\x03z7\r\x01\x01\x0f"},
+	{"internal/poll", "nO\x1f\x159\r\x01\x01\f\x06"},
+	{"internal/profile", "\x03\x04g\x03\x80\x017\v\x01\x01\x10"},
 	{"internal/profilerecord", ""},
-	{"internal/race", "\x94\x01\xb1\x01"},
-	{"internal/reflectlite", "\x94\x01 3<\""},
-	{"internal/runtime/atomic", "\xc5\x02"},
-	{"internal/runtime/exithook", "\xca\x01{"},
-	{"internal/runtime/maps", "\x94\x01\x01\x1f\v\t\x05\x01w"},
-	{"internal/runtime/math", "\xb4\x01"},
-	{"internal/runtime/sys", "\xb4\x01\x04"},
-	{"internal/runtime/syscall", "\xc5\x02"},
-	{"internal/saferio", "\xea\x01["},
-	{"internal/singleflight", "\xb2\x02"},
-	{"internal/stringslite", "\x98\x01\xad\x01"},
-	{"internal/sync", "\x94\x01 \x14k\x12"},
-	{"internal/synctest", "\xc5\x02"},
-	{"internal/syscall/execenv", "\xb4\x02"},
-	{"internal/syscall/unix", "\xa3\x02\x10\x01\x11"},
-	{"internal/sysinfo", "\x02\x01\xaa\x01=,\x1a\x02"},
+	{"internal/race", "\x94\x01\xb7\x01"},
+	{"internal/reflectlite", "\x94\x01!9<!"},
+	{"internal/runtime/atomic", "\xb5\x01\x96\x01"},
+	{"internal/runtime/cgroup", "\x98\x01:\x02w"},
+	{"internal/runtime/exithook", "\xcb\x01\x80\x01"},
+	{"internal/runtime/gc", "\xb5\x01"},
+	{"internal/runtime/maps", "\x94\x01\x01 \v\t\a\x03x"},
+	{"internal/runtime/math", "\xb5\x01"},
+	{"internal/runtime/startlinetest", ""},
+	{"internal/runtime/strconv", "\xd0\x01"},
+	{"internal/runtime/sys", "\xb5\x01\x04"},
+	{"internal/runtime/syscall", "\xb5\x01\x96\x01"},
+	{"internal/runtime/wasitest", ""},
+	{"internal/saferio", "\xf1\x01Z"},
+	{"internal/singleflight", "\xb7\x02"},
+	{"internal/stringslite", "\x98\x01\xb3\x01"},
+	{"internal/sync", "\x94\x01!\x14o\x13"},
+	{"internal/synctest", "\x94\x01\xb7\x01"},
+	{"internal/syscall/execenv", "\xb9\x02"},
+	{"internal/syscall/unix", "\xaa\x02\x0e\x01\x12"},
+	{"internal/sysinfo", "\x02\x01\xab\x01C,\x18\x02"},
 	{"internal/syslist", ""},
-	{"internal/testenv", "\x03\n`\x02\x01*\x1a\x10'+\x01\x05\a\f\x01\x02\x02\x01\n"},
-	{"internal/testlog", "\xb2\x02\x01\x12"},
-	{"internal/testpty", "m\x03\xa6\x01"},
-	{"internal/trace", "\x02\x01\x01\x06\\\a\x03n\x03\x03\x06\x03\n6\x01\x02\x0f\x06"},
-	{"internal/trace/internal/testgen", "\x03c\nl\x03\x02\x03\x011\v\x0f"},
-	{"internal/trace/internal/tracev1", "\x03\x01b\a\x03t\x06\r6\x01"},
-	{"internal/trace/raw", "\x02d\nq\x03\x06E\x01\x11"},
-	{"internal/trace/testtrace", "\x02\x01j\x03l\x03\x06\x057\f\x02\x01"},
+	{"internal/testenv", "\x03\na\x02\x01)\x1b\x10-+\x01\x05\a\n\x01\x02\x02\x01\v"},
+	{"internal/testhash", "\x03\x80\x01n\x118\v"},
+	{"internal/testlog", "\xb7\x02\x01\x13"},
+	{"internal/testpty", "n\x03\xac\x01"},
+	{"internal/trace", "\x02\x01\x01\x06]\a\x03t\x03\x03\x06\x03\t5\x01\x01\x01\x10\x06"},
+	{"internal/trace/internal/testgen", "\x03d\nr\x03\x02\x03\x011\v\r\x10"},
+	{"internal/trace/internal/tracev1", "\x03\x01c\a\x03z\x06\f5\x01"},
+	{"internal/trace/raw", "\x02e\nw\x03\x06C\x01\x12"},
+	{"internal/trace/testtrace", "\x02\x01k\x03r\x03\x05\x01\x057\n\x02\x01"},
 	{"internal/trace/tracev2", ""},
-	{"internal/trace/traceviewer", "\x02]\v\x06\x1a<\x16\a\a\x04\t\n\x15\x01\x05\a\f\x01\x02\r"},
+	{"internal/trace/traceviewer", "\x02^\v\x06\x19=\x1c\a\a\x04\b\v\x15\x01\x05\a\n\x01\x02\x0e"},
 	{"internal/trace/traceviewer/format", ""},
-	{"internal/trace/version", "pq\t"},
-	{"internal/txtar", "\x03m\xa6\x01\x1a"},
-	{"internal/types/errors", "\xaf\x02"},
-	{"internal/unsafeheader", "\xc5\x02"},
-	{"internal/xcoff", "Y\r\a\x03`\x1a,\x19\x01"},
-	{"internal/zstd", "f\a\x03z\x0f"},
-	{"io", "m\xc5\x01"},
-	{"io/fs", "m+*(1\x12\x12\x04"},
-	{"io/ioutil", "\xea\x01\x01+\x17\x03"},
-	{"iter", "\xc8\x01[\""},
-	{"log", "pz\x05'\r\x0f\x01\f"},
+	{"internal/trace/version", "qw\t"},
+	{"internal/txtar", "\x03n\xac\x01\x18"},
+	{"internal/types/errors", "\xb4\x02"},
+	{"internal/unsafeheader", "\xcb\x02"},
+	{"internal/xcoff", "Z\r\a\x03e\x1b,\x17\x01"},
+	{"internal/zstd", "g\a\x03\x80\x01\x0f"},
+	{"io", "n\xc9\x01"},
+	{"io/fs", "n*+.1\x10\x13\x04"},
+	{"io/ioutil", "\xf1\x01\x01+\x15\x03"},
+	{"iter", "\xc9\x01a!"},
+	{"log", "q\x80\x01\x05'\r\r\x01\r"},
 	{"log/internal", ""},
-	{"log/slog", "\x03\nT\t\x03\x03z\x04\x01\x02\x02\x04'\x05\n\x02\x01\x02\x01\f\x02\x02\x02"},
+	{"log/slog", "\x03\nU\t\x03\x03\x80\x01\x04\x01\x02\x02\x03(\x05\b\x02\x01\x02\x01\r\x02\x02\x02"},
 	{"log/slog/internal", ""},
-	{"log/slog/internal/benchmarks", "\r`\x03z\x06\x03<\x10"},
-	{"log/slog/internal/buffer", "\xb2\x02"},
-	{"log/slog/internal/slogtest", "\xf0\x01"},
-	{"log/syslog", "m\x03~\x12\x16\x1a\x02\r"},
-	{"maps", "\xed\x01X"},
-	{"math", "\xad\x01LL"},
-	{"math/big", "\x03j\x03)\x14=\r\x02\x024\x01\x02\x13"},
-	{"math/bits", "\xc5\x02"},
-	{"math/cmplx", "\xf7\x01\x02"},
-	{"math/rand", "\xb5\x01B;\x01\x12"},
-	{"math/rand/v2", "m,\x02\\\x02L"},
-	{"mime", "\x02\x01b\b\x03z\f \x17\x03\x02\x0f\x02"},
-	{"mime/multipart", "\x02\x01G#\x03E5\f\x01\x06\x02\x15\x02\x06\x11\x02\x01\x15"},
-	{"mime/quotedprintable", "\x02\x01mz"},
-	{"net", "\x04\t`+\x1d\a\x04\x05\f\x01\x04\x14\x01%\x06\r\n\x05\x01\x01\v\x06\a"},
-	{"net/http", "\x02\x01\x04\x04\x02=\b\x13\x01\a\x03E5\x01\x03\b\x01\x02\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\n\x01\x01\x01\x02\x01\x01\v\x02\x02\x02\b\x01\x01\x01"},
-	{"net/http/cgi", "\x02P\x1b\x03z\x04\b\n\x01\x13\x01\x01\x01\x04\x01\x05\x02\n\x02\x01\x0f\x0e"},
-	{"net/http/cookiejar", "\x04i\x03\x90\x01\x01\b\f\x18\x03\x02\r\x04"},
-	{"net/http/fcgi", "\x02\x01\nY\a\x03z\x16\x01\x01\x14\x1a\x02\r"},
-	{"net/http/httptest", "\x02\x01\nE\x02\x1b\x01z\x04\x12\x01\n\t\x02\x19\x01\x02\r\x0e"},
-	{"net/http/httptrace", "\rEn@\x14\n!"},
-	{"net/http/httputil", "\x02\x01\n`\x03z\x04\x0f\x03\x01\x05\x02\x01\v\x01\x1b\x02\r\x0e"},
-	{"net/http/internal", "\x02\x01j\x03z"},
-	{"net/http/internal/ascii", "\xb0\x02\x11"},
-	{"net/http/internal/httpcommon", "\r`\x03\x96\x01\x0e\x01\x19\x01\x01\x02\x1b\x02"},
-	{"net/http/internal/testcert", "\xb0\x02"},
-	{"net/http/pprof", "\x02\x01\nc\x19,\x11$\x04\x13\x14\x01\r\x06\x03\x01\x02\x01\x0f"},
+	{"log/slog/internal/benchmarks", "\ra\x03\x80\x01\x06\x03:\x11"},
+	{"log/slog/internal/buffer", "\xb7\x02"},
+	{"log/syslog", "n\x03\x84\x01\x12\x16\x18\x02\x0e"},
+	{"maps", "\xf4\x01W"},
+	{"math", "\xae\x01RK"},
+	{"math/big", "\x03k\x03(\x15C\f\x03\x020\x02\x01\x02\x14"},
+	{"math/big/internal/asmgen", "\x03\x01m\x8f\x012\x03"},
+	{"math/bits", "\xcb\x02"},
+	{"math/cmplx", "\xfd\x01\x03"},
+	{"math/rand", "\xb6\x01G:\x01\x13"},
+	{"math/rand/v2", "n+\x03a\x03K"},
+	{"mime", "\x02\x01c\b\x03\x80\x01\v!\x15\x03\x02\x10\x02"},
+	{"mime/multipart", "\x02\x01H#\x03E;\v\x01\a\x02\x15\x02\x06\x0f\x02\x01\x16"},
+	{"mime/quotedprintable", "\x02\x01n\x80\x01"},
+	{"net", "\x04\ta*\x1e\a\x04\x05\x11\x01\x04\x15\x01%\x06\r\b\x05\x01\x01\f\x06\a"},
+	{"net/http", "\x02\x01\x04\x04\x02>\b\x13\x01\a\x03E;\x01\x03\a\x01\x03\x02\x02\x01\x02\x06\x02\x01\x01\n\x01\x01\x05\x01\x02\x05\b\x01\x01\x01\x02\x01\r\x02\x02\x02\b\x01\x01\x01"},
+	{"net/http/cgi", "\x02Q\x1b\x03\x80\x01\x04\a\v\x01\x13\x01\x01\x01\x04\x01\x05\x02\b\x02\x01\x10\x0e"},
+	{"net/http/cookiejar", "\x04j\x03\x96\x01\x01\b\f\x16\x03\x02\x0e\x04"},
+	{"net/http/fcgi", "\x02\x01\nZ\a\x03\x80\x01\x16\x01\x01\x14\x18\x02\x0e"},
+	{"net/http/httptest", "\x02\x01\nF\x02\x1b\x01\x80\x01\x04\x12\x01\n\t\x02\x17\x01\x02\x0e\x0e"},
+	{"net/http/httptrace", "\rFnF\x14\n "},
+	{"net/http/httputil", "\x02\x01\na\x03\x80\x01\x04\x0f\x03\x01\x05\x02\x01\v\x01\x19\x02\x0e\x0e"},
+	{"net/http/internal", "\x02\x01k\x03\x80\x01"},
+	{"net/http/internal/ascii", "\xb5\x02\x12"},
+	{"net/http/internal/httpcommon", "\ra\x03\x9c\x01\x0e\x01\x17\x01\x01\x02\x1c\x02"},
+	{"net/http/internal/testcert", "\xb5\x02"},
+	{"net/http/pprof", "\x02\x01\nd\x18-\x11*\x04\x13\x14\x01\r\x04\x03\x01\x02\x01\x10"},
 	{"net/internal/cgotest", ""},
-	{"net/internal/socktest", "p\xc2\x01\x02"},
-	{"net/mail", "\x02k\x03z\x04\x0f\x03\x14\x1c\x02\r\x04"},
-	{"net/netip", "\x04i+\x01#;\x026\x15"},
-	{"net/rpc", "\x02f\x05\x03\x10\n`\x04\x12\x01\x1d\x0f\x03\x02"},
-	{"net/rpc/jsonrpc", "j\x03\x03z\x16\x11!"},
-	{"net/smtp", "\x19.\v\x13\b\x03z\x16\x14\x1c"},
-	{"net/textproto", "\x02\x01j\x03z\r\t/\x01\x02\x13"},
-	{"net/url", "m\x03\x86\x01%\x12\x02\x01\x15"},
-	{"os", "m+\x01\x18\x03\b\t\r\x03\x01\x04\x10\x018\n\x05\x01\x01\v\x06"},
-	{"os/exec", "\x03\n`H \x01\x14\x01+\x06\a\f\x01\x04\v"},
-	{"os/exec/internal/fdtest", "\xb4\x02"},
-	{"os/signal", "\r\x89\x02\x17\x05\x02"},
-	{"os/user", "\x02\x01j\x03z,\r\f\x01\x02"},
-	{"path", "m+\xab\x01"},
-	{"path/filepath", "m+\x19:+\r\n\x03\x04\x0f"},
-	{"plugin", "m"},
-	{"reflect", "m'\x04\x1c\b\f\x04\x02\x19\x10,\f\x03\x0f\x02\x02"},
+	{"net/internal/socktest", "q\xc6\x01\x02"},
+	{"net/mail", "\x02l\x03\x80\x01\x04\x0f\x03\x14\x1a\x02\x0e\x04"},
+	{"net/netip", "\x04j*\x01$@\x034\x16"},
+	{"net/rpc", "\x02g\x05\x03\x0f\ng\x04\x12\x01\x1d\r\x03\x02"},
+	{"net/rpc/jsonrpc", "k\x03\x03\x80\x01\x16\x11\x1f"},
+	{"net/smtp", "\x19/\v\x13\b\x03\x80\x01\x16\x14\x1a"},
+	{"net/textproto", "\x02\x01k\x03\x80\x01\f\n-\x01\x02\x14"},
+	{"net/url", "n\x03\x8b\x01&\x10\x02\x01\x16"},
+	{"os", "n*\x01\x19\x03\b\t\x12\x03\x01\x05\x10\x018\b\x05\x01\x01\f\x06"},
+	{"os/exec", "\x03\naH%\x01\x15\x01+\x06\a\n\x01\x04\f"},
+	{"os/exec/internal/fdtest", "\xb9\x02"},
+	{"os/signal", "\r\x90\x02\x15\x05\x02"},
+	{"os/user", "\x02\x01k\x03\x80\x01,\r\n\x01\x02"},
+	{"path", "n*\xb1\x01"},
+	{"path/filepath", "n*\x1a@+\r\b\x03\x04\x10"},
+	{"plugin", "n"},
+	{"reflect", "n&\x04\x1d\b\f\x06\x04\x1b\x06\t-\n\x03\x10\x02\x02"},
 	{"reflect/internal/example1", ""},
 	{"reflect/internal/example2", ""},
-	{"regexp", "\x03\xe7\x018\v\x02\x01\x02\x0f\x02"},
-	{"regexp/syntax", "\xad\x02\x01\x01\x01\x11\x02"},
-	{"runtime", "\x94\x01\x04\x01\x02\f\x06\a\x02\x01\x01\x0f\x03\x01\x01\x01\x01\x01\x03\x0fd"},
-	{"runtime/coverage", "\x9f\x01K"},
-	{"runtime/debug", "pUQ\r\n\x02\x01\x0f\x06"},
-	{"runtime/internal/startlinetest", ""},
-	{"runtime/internal/wasitest", ""},
-	{"runtime/metrics", "\xb6\x01A,\""},
-	{"runtime/pprof", "\x02\x01\x01\x03\x06Y\a\x03$3#\r\x1f\r\n\x01\x01\x01\x02\x02\b\x03\x06"},
-	{"runtime/race", "\xab\x02"},
+	{"regexp", "\x03\xee\x018\t\x02\x01\x02\x10\x02"},
+	{"regexp/syntax", "\xb2\x02\x01\x01\x01\x02\x10\x02"},
+	{"runtime", "\x94\x01\x04\x01\x03\f\x06\a\x02\x01\x01\x0f\x03\x01\x01\x01\x01\x01\x02\x01\x01\x04\x10c"},
+	{"runtime/coverage", "\xa0\x01Q"},
+	{"runtime/debug", "qUW\r\b\x02\x01\x10\x06"},
+	{"runtime/metrics", "\xb7\x01F-!"},
+	{"runtime/pprof", "\x02\x01\x01\x03\x06Z\a\x03#4)\f \r\b\x01\x01\x01\x02\x02\t\x03\x06"},
+	{"runtime/race", "\xb0\x02"},
 	{"runtime/race/internal/amd64v1", ""},
-	{"runtime/trace", "\rcz9\x0f\x01\x12"},
-	{"slices", "\x04\xe9\x01\fL"},
-	{"sort", "\xc9\x0104"},
-	{"strconv", "m+:%\x02J"},
-	{"strings", "m'\x04:\x18\x03\f9\x0f\x02\x02"},
+	{"runtime/trace", "\ra\x03w\t9\b\x05\x01\r\x06"},
+	{"slices", "\x04\xf0\x01\fK"},
+	{"sort", "\xca\x0162"},
+	{"strconv", "n*@%\x03I"},
+	{"strings", "n&\x04@\x19\x03\f7\x10\x02\x02"},
 	{"structs", ""},
-	{"sync", "\xc8\x01\vP\x10\x12"},
-	{"sync/atomic", "\xc5\x02"},
-	{"syscall", "m(\x03\x01\x1b\b\x03\x03\x06\aT\n\x05\x01\x12"},
-	{"testing", "\x03\n`\x02\x01X\x0f\x13\r\x04\x1b\x06\x02\x05\x02\a\x01\x02\x01\x02\x01\f\x02\x02\x02"},
-	{"testing/fstest", "m\x03z\x01\v%\x12\x03\b\a"},
-	{"testing/internal/testdeps", "\x02\v\xa6\x01'\x10,\x03\x05\x03\b\a\x02\r"},
-	{"testing/iotest", "\x03j\x03z\x04"},
-	{"testing/quick", "o\x01\x87\x01\x04#\x12\x0f"},
-	{"testing/slogtest", "\r`\x03\x80\x01.\x05\x12\n"},
-	{"text/scanner", "\x03mz,+\x02"},
-	{"text/tabwriter", "pzY"},
-	{"text/template", "m\x03B8\x01\v\x1f\x01\x05\x01\x02\x05\r\x02\f\x03\x02"},
-	{"text/template/parse", "\x03m\xb3\x01\f\x01\x11\x02"},
-	{"time", "m+\x1d\x1d'*\x0f\x02\x11"},
-	{"time/tzdata", "m\xc7\x01\x11"},
+	{"sync", "\xc9\x01\x10\x01P\x0e\x13"},
+	{"sync/atomic", "\xcb\x02"},
+	{"syscall", "n'\x03\x01\x1c\b\x03\x03\x06\vV\b\x05\x01\x13"},
+	{"testing", "\x03\na\x02\x01X\x14\x14\f\x05\x1b\x06\x02\x05\x02\x05\x01\x02\x01\x02\x01\r\x02\x02\x02"},
+	{"testing/fstest", "n\x03\x80\x01\x01\n&\x10\x03\b\b"},
+	{"testing/internal/testdeps", "\x02\v\xa7\x01-\x10,\x03\x05\x03\x06\a\x02\x0e"},
+	{"testing/iotest", "\x03k\x03\x80\x01\x04"},
+	{"testing/quick", "p\x01\x8c\x01\x05#\x10\x10"},
+	{"testing/slogtest", "\ra\x03\x86\x01.\x05\x10\v"},
+	{"testing/synctest", "\xda\x01`\x11"},
+	{"text/scanner", "\x03n\x80\x01,*\x02"},
+	{"text/tabwriter", "q\x80\x01X"},
+	{"text/template", "n\x03B>\x01\n \x01\x05\x01\x02\x05\v\x02\r\x03\x02"},
+	{"text/template/parse", "\x03n\xb9\x01\n\x01\x12\x02"},
+	{"time", "n*\x1e\"(*\r\x02\x12"},
+	{"time/tzdata", "n\xcb\x01\x12"},
 	{"unicode", ""},
 	{"unicode/utf16", ""},
 	{"unicode/utf8", ""},
-	{"unique", "\x94\x01>\x01P\x0f\x13\x12"},
+	{"unique", "\x94\x01!#\x01Q\r\x01\x13\x12"},
 	{"unsafe", ""},
-	{"vendor/golang.org/x/crypto/chacha20", "\x10V\a\x8c\x01*'"},
-	{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10V\a\xd9\x01\x04\x01\a"},
-	{"vendor/golang.org/x/crypto/cryptobyte", "c\n\x03\x88\x01&!\n"},
+	{"vendor/golang.org/x/crypto/chacha20", "\x10W\a\x92\x01*&"},
+	{"vendor/golang.org/x/crypto/chacha20poly1305", "\x10W\a\xde\x01\x04\x01\a"},
+	{"vendor/golang.org/x/crypto/cryptobyte", "d\n\x03\x8d\x01' \n"},
 	{"vendor/golang.org/x/crypto/cryptobyte/asn1", ""},
-	{"vendor/golang.org/x/crypto/internal/alias", "\xc5\x02"},
-	{"vendor/golang.org/x/crypto/internal/poly1305", "Q\x15\x93\x01"},
-	{"vendor/golang.org/x/net/dns/dnsmessage", "m"},
-	{"vendor/golang.org/x/net/http/httpguts", "\x80\x02\x14\x1c\x13\r"},
-	{"vendor/golang.org/x/net/http/httpproxy", "m\x03\x90\x01\x15\x01\x1a\x13\r"},
-	{"vendor/golang.org/x/net/http2/hpack", "\x03j\x03zH"},
-	{"vendor/golang.org/x/net/idna", "p\x87\x019\x13\x10\x02\x01"},
-	{"vendor/golang.org/x/net/nettest", "\x03c\a\x03z\x11\x05\x16\x01\f\f\x01\x02\x02\x01\n"},
-	{"vendor/golang.org/x/sys/cpu", "\x96\x02\r\f\x01\x15"},
-	{"vendor/golang.org/x/text/secure/bidirule", "m\xd6\x01\x11\x01"},
-	{"vendor/golang.org/x/text/transform", "\x03j}Y"},
-	{"vendor/golang.org/x/text/unicode/bidi", "\x03\be~@\x15"},
-	{"vendor/golang.org/x/text/unicode/norm", "f\nzH\x11\x11"},
-	{"weak", "\x94\x01\x8f\x01\""},
+	{"vendor/golang.org/x/crypto/internal/alias", "\xcb\x02"},
+	{"vendor/golang.org/x/crypto/internal/poly1305", "R\x15\x99\x01"},
+	{"vendor/golang.org/x/net/dns/dnsmessage", "n"},
+	{"vendor/golang.org/x/net/http/httpguts", "\x87\x02\x14\x1a\x14\r"},
+	{"vendor/golang.org/x/net/http/httpproxy", "n\x03\x96\x01\x10\x05\x01\x18\x14\r"},
+	{"vendor/golang.org/x/net/http2/hpack", "\x03k\x03\x80\x01F"},
+	{"vendor/golang.org/x/net/idna", "q\x8c\x018\x14\x10\x02\x01"},
+	{"vendor/golang.org/x/net/nettest", "\x03d\a\x03\x80\x01\x11\x05\x16\x01\f\n\x01\x02\x02\x01\v"},
+	{"vendor/golang.org/x/sys/cpu", "\x9d\x02\r\n\x01\x16"},
+	{"vendor/golang.org/x/text/secure/bidirule", "n\xdb\x01\x11\x01"},
+	{"vendor/golang.org/x/text/transform", "\x03k\x83\x01X"},
+	{"vendor/golang.org/x/text/unicode/bidi", "\x03\bf\x84\x01>\x16"},
+	{"vendor/golang.org/x/text/unicode/norm", "g\n\x80\x01F\x12\x11"},
+	{"weak", "\x94\x01\x96\x01!"},
 }
diff --git a/vendor/golang.org/x/tools/internal/stdlib/manifest.go b/vendor/golang.org/x/tools/internal/stdlib/manifest.go
index 64f0326b6..c1faa50d3 100644
--- a/vendor/golang.org/x/tools/internal/stdlib/manifest.go
+++ b/vendor/golang.org/x/tools/internal/stdlib/manifest.go
@@ -502,6 +502,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"MD4", Const, 0, ""},
 		{"MD5", Const, 0, ""},
 		{"MD5SHA1", Const, 0, ""},
+		{"MessageSigner", Type, 25, ""},
 		{"PrivateKey", Type, 0, ""},
 		{"PublicKey", Type, 2, ""},
 		{"RIPEMD160", Const, 0, ""},
@@ -517,6 +518,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"SHA512", Const, 0, ""},
 		{"SHA512_224", Const, 5, ""},
 		{"SHA512_256", Const, 5, ""},
+		{"SignMessage", Func, 25, "func(signer Signer, rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)"},
 		{"Signer", Type, 4, ""},
 		{"SignerOpts", Type, 4, ""},
 	},
@@ -600,10 +602,12 @@ var PackageSymbols = map[string][]Symbol{
 		{"X25519", Func, 20, "func() Curve"},
 	},
 	"crypto/ecdsa": {
+		{"(*PrivateKey).Bytes", Method, 25, ""},
 		{"(*PrivateKey).ECDH", Method, 20, ""},
 		{"(*PrivateKey).Equal", Method, 15, ""},
 		{"(*PrivateKey).Public", Method, 4, ""},
 		{"(*PrivateKey).Sign", Method, 4, ""},
+		{"(*PublicKey).Bytes", Method, 25, ""},
 		{"(*PublicKey).ECDH", Method, 20, ""},
 		{"(*PublicKey).Equal", Method, 15, ""},
 		{"(PrivateKey).Add", Method, 0, ""},
@@ -619,6 +623,8 @@ var PackageSymbols = map[string][]Symbol{
 		{"(PublicKey).ScalarBaseMult", Method, 0, ""},
 		{"(PublicKey).ScalarMult", Method, 0, ""},
 		{"GenerateKey", Func, 0, "func(c elliptic.Curve, rand io.Reader) (*PrivateKey, error)"},
+		{"ParseRawPrivateKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PrivateKey, error)"},
+		{"ParseUncompressedPublicKey", Func, 25, "func(curve elliptic.Curve, data []byte) (*PublicKey, error)"},
 		{"PrivateKey", Type, 0, ""},
 		{"PrivateKey.D", Field, 0, ""},
 		{"PrivateKey.PublicKey", Field, 0, ""},
@@ -815,6 +821,7 @@ var PackageSymbols = map[string][]Symbol{
 	"crypto/sha3": {
 		{"(*SHA3).AppendBinary", Method, 24, ""},
 		{"(*SHA3).BlockSize", Method, 24, ""},
+		{"(*SHA3).Clone", Method, 25, ""},
 		{"(*SHA3).MarshalBinary", Method, 24, ""},
 		{"(*SHA3).Reset", Method, 24, ""},
 		{"(*SHA3).Size", Method, 24, ""},
@@ -967,6 +974,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"Config.GetCertificate", Field, 4, ""},
 		{"Config.GetClientCertificate", Field, 8, ""},
 		{"Config.GetConfigForClient", Field, 8, ""},
+		{"Config.GetEncryptedClientHelloKeys", Field, 25, ""},
 		{"Config.InsecureSkipVerify", Field, 0, ""},
 		{"Config.KeyLogWriter", Field, 8, ""},
 		{"Config.MaxVersion", Field, 2, ""},
@@ -5463,6 +5471,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"ParenExpr.X", Field, 0, ""},
 		{"Pkg", Const, 0, ""},
 		{"Preorder", Func, 23, "func(root Node) iter.Seq[Node]"},
+		{"PreorderStack", Func, 25, "func(root Node, stack []Node, f func(n Node, stack []Node) bool)"},
 		{"Print", Func, 0, "func(fset *token.FileSet, x any) error"},
 		{"RECV", Const, 0, ""},
 		{"RangeStmt", Type, 0, ""},
@@ -5933,6 +5942,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*File).SetLines", Method, 0, ""},
 		{"(*File).SetLinesForContent", Method, 0, ""},
 		{"(*File).Size", Method, 0, ""},
+		{"(*FileSet).AddExistingFiles", Method, 25, ""},
 		{"(*FileSet).AddFile", Method, 0, ""},
 		{"(*FileSet).Base", Method, 0, ""},
 		{"(*FileSet).File", Method, 0, ""},
@@ -6382,7 +6392,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"Label", Type, 5, ""},
 		{"LocalVar", Const, 25, ""},
 		{"LookupFieldOrMethod", Func, 5, "func(T Type, addressable bool, pkg *Package, name string) (obj Object, index []int, indirect bool)"},
-		{"LookupSelection", Func, 25, ""},
+		{"LookupSelection", Func, 25, "func(T Type, addressable bool, pkg *Package, name string) (Selection, bool)"},
 		{"Map", Type, 5, ""},
 		{"MethodExpr", Const, 5, ""},
 		{"MethodSet", Type, 5, ""},
@@ -6490,9 +6500,11 @@ var PackageSymbols = map[string][]Symbol{
 		{"Lang", Func, 22, "func(x string) string"},
 	},
 	"hash": {
+		{"Cloner", Type, 25, ""},
 		{"Hash", Type, 0, ""},
 		{"Hash32", Type, 0, ""},
 		{"Hash64", Type, 0, ""},
+		{"XOF", Type, 25, ""},
 	},
 	"hash/adler32": {
 		{"Checksum", Func, 0, "func(data []byte) uint32"},
@@ -6533,6 +6545,7 @@ var PackageSymbols = map[string][]Symbol{
 	},
 	"hash/maphash": {
 		{"(*Hash).BlockSize", Method, 14, ""},
+		{"(*Hash).Clone", Method, 25, ""},
 		{"(*Hash).Reset", Method, 14, ""},
 		{"(*Hash).Seed", Method, 14, ""},
 		{"(*Hash).SetSeed", Method, 14, ""},
@@ -7133,7 +7146,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"FormatFileInfo", Func, 21, "func(info FileInfo) string"},
 		{"Glob", Func, 16, "func(fsys FS, pattern string) (matches []string, err error)"},
 		{"GlobFS", Type, 16, ""},
-		{"Lstat", Func, 25, ""},
+		{"Lstat", Func, 25, "func(fsys FS, name string) (FileInfo, error)"},
 		{"ModeAppend", Const, 16, ""},
 		{"ModeCharDevice", Const, 16, ""},
 		{"ModeDevice", Const, 16, ""},
@@ -7158,7 +7171,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"ReadDirFile", Type, 16, ""},
 		{"ReadFile", Func, 16, "func(fsys FS, name string) ([]byte, error)"},
 		{"ReadFileFS", Type, 16, ""},
-		{"ReadLink", Func, 25, ""},
+		{"ReadLink", Func, 25, "func(fsys FS, name string) (string, error)"},
 		{"ReadLinkFS", Type, 25, ""},
 		{"SkipAll", Var, 20, ""},
 		{"SkipDir", Var, 16, ""},
@@ -7275,6 +7288,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"(Record).Attrs", Method, 21, ""},
 		{"(Record).Clone", Method, 21, ""},
 		{"(Record).NumAttrs", Method, 21, ""},
+		{"(Record).Source", Method, 25, ""},
 		{"(Value).Any", Method, 21, ""},
 		{"(Value).Bool", Method, 21, ""},
 		{"(Value).Duration", Method, 21, ""},
@@ -7306,6 +7320,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"Float64", Func, 21, "func(key string, v float64) Attr"},
 		{"Float64Value", Func, 21, "func(v float64) Value"},
 		{"Group", Func, 21, "func(key string, args ...any) Attr"},
+		{"GroupAttrs", Func, 25, "func(key string, attrs ...Attr) Attr"},
 		{"GroupValue", Func, 21, "func(as ...Attr) Value"},
 		{"Handler", Type, 21, ""},
 		{"HandlerOptions", Type, 21, ""},
@@ -7916,7 +7931,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*Writer).WriteField", Method, 0, ""},
 		{"ErrMessageTooLarge", Var, 9, ""},
 		{"File", Type, 0, ""},
-		{"FileContentDisposition", Func, 25, ""},
+		{"FileContentDisposition", Func, 25, "func(fieldname string, filename string) string"},
 		{"FileHeader", Type, 0, ""},
 		{"FileHeader.Filename", Field, 0, ""},
 		{"FileHeader.Header", Field, 0, ""},
@@ -8294,6 +8309,11 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*Client).PostForm", Method, 0, ""},
 		{"(*Cookie).String", Method, 0, ""},
 		{"(*Cookie).Valid", Method, 18, ""},
+		{"(*CrossOriginProtection).AddInsecureBypassPattern", Method, 25, ""},
+		{"(*CrossOriginProtection).AddTrustedOrigin", Method, 25, ""},
+		{"(*CrossOriginProtection).Check", Method, 25, ""},
+		{"(*CrossOriginProtection).Handler", Method, 25, ""},
+		{"(*CrossOriginProtection).SetDenyHandler", Method, 25, ""},
 		{"(*MaxBytesError).Error", Method, 19, ""},
 		{"(*ProtocolError).Error", Method, 0, ""},
 		{"(*ProtocolError).Is", Method, 21, ""},
@@ -8388,6 +8408,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"Cookie.Unparsed", Field, 0, ""},
 		{"Cookie.Value", Field, 0, ""},
 		{"CookieJar", Type, 0, ""},
+		{"CrossOriginProtection", Type, 25, ""},
 		{"DefaultClient", Var, 0, ""},
 		{"DefaultMaxHeaderBytes", Const, 0, ""},
 		{"DefaultMaxIdleConnsPerHost", Const, 0, ""},
@@ -8460,6 +8481,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"MethodPost", Const, 6, ""},
 		{"MethodPut", Const, 6, ""},
 		{"MethodTrace", Const, 6, ""},
+		{"NewCrossOriginProtection", Func, 25, "func() *CrossOriginProtection"},
 		{"NewFileTransport", Func, 0, "func(fs FileSystem) RoundTripper"},
 		{"NewFileTransportFS", Func, 22, "func(fsys fs.FS) RoundTripper"},
 		{"NewRequest", Func, 0, "func(method string, url string, body io.Reader) (*Request, error)"},
@@ -9174,15 +9196,19 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*Root).Link", Method, 25, ""},
 		{"(*Root).Lstat", Method, 24, ""},
 		{"(*Root).Mkdir", Method, 24, ""},
+		{"(*Root).MkdirAll", Method, 25, ""},
 		{"(*Root).Name", Method, 24, ""},
 		{"(*Root).Open", Method, 24, ""},
 		{"(*Root).OpenFile", Method, 24, ""},
 		{"(*Root).OpenRoot", Method, 24, ""},
+		{"(*Root).ReadFile", Method, 25, ""},
 		{"(*Root).Readlink", Method, 25, ""},
 		{"(*Root).Remove", Method, 24, ""},
+		{"(*Root).RemoveAll", Method, 25, ""},
 		{"(*Root).Rename", Method, 25, ""},
 		{"(*Root).Stat", Method, 24, ""},
 		{"(*Root).Symlink", Method, 25, ""},
+		{"(*Root).WriteFile", Method, 25, ""},
 		{"(*SyscallError).Error", Method, 0, ""},
 		{"(*SyscallError).Timeout", Method, 10, ""},
 		{"(*SyscallError).Unwrap", Method, 13, ""},
@@ -9623,6 +9649,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"StructTag", Type, 0, ""},
 		{"Swapper", Func, 8, "func(slice any) func(i int, j int)"},
 		{"Type", Type, 0, ""},
+		{"TypeAssert", Func, 25, "func[T any](v Value) (T, bool)"},
 		{"TypeFor", Func, 22, "func[T any]() Type"},
 		{"TypeOf", Func, 0, "func(i any) Type"},
 		{"Uint", Const, 0, ""},
@@ -9909,6 +9936,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"SetBlockProfileRate", Func, 1, "func(rate int)"},
 		{"SetCPUProfileRate", Func, 0, "func(hz int)"},
 		{"SetCgoTraceback", Func, 7, "func(version int, traceback unsafe.Pointer, context unsafe.Pointer, symbolizer unsafe.Pointer)"},
+		{"SetDefaultGOMAXPROCS", Func, 25, "func()"},
 		{"SetFinalizer", Func, 0, "func(obj any, finalizer any)"},
 		{"SetMutexProfileFraction", Func, 8, "func(rate int) int"},
 		{"Stack", Func, 0, "func(buf []byte, all bool) int"},
@@ -10021,11 +10049,20 @@ var PackageSymbols = map[string][]Symbol{
 		{"WriteHeapProfile", Func, 0, "func(w io.Writer) error"},
 	},
 	"runtime/trace": {
+		{"(*FlightRecorder).Enabled", Method, 25, ""},
+		{"(*FlightRecorder).Start", Method, 25, ""},
+		{"(*FlightRecorder).Stop", Method, 25, ""},
+		{"(*FlightRecorder).WriteTo", Method, 25, ""},
 		{"(*Region).End", Method, 11, ""},
 		{"(*Task).End", Method, 11, ""},
+		{"FlightRecorder", Type, 25, ""},
+		{"FlightRecorderConfig", Type, 25, ""},
+		{"FlightRecorderConfig.MaxBytes", Field, 25, ""},
+		{"FlightRecorderConfig.MinAge", Field, 25, ""},
 		{"IsEnabled", Func, 11, "func() bool"},
 		{"Log", Func, 11, "func(ctx context.Context, category string, message string)"},
 		{"Logf", Func, 11, "func(ctx context.Context, category string, format string, args ...any)"},
+		{"NewFlightRecorder", Func, 25, "func(cfg FlightRecorderConfig) *FlightRecorder"},
 		{"NewTask", Func, 11, "func(pctx context.Context, taskType string) (ctx context.Context, task *Task)"},
 		{"Region", Type, 11, ""},
 		{"Start", Func, 5, "func(w io.Writer) error"},
@@ -16642,6 +16679,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"ValueOf", Func, 0, ""},
 	},
 	"testing": {
+		{"(*B).Attr", Method, 25, ""},
 		{"(*B).Chdir", Method, 24, ""},
 		{"(*B).Cleanup", Method, 14, ""},
 		{"(*B).Context", Method, 24, ""},
@@ -16658,6 +16696,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*B).Logf", Method, 0, ""},
 		{"(*B).Loop", Method, 24, ""},
 		{"(*B).Name", Method, 8, ""},
+		{"(*B).Output", Method, 25, ""},
 		{"(*B).ReportAllocs", Method, 1, ""},
 		{"(*B).ReportMetric", Method, 13, ""},
 		{"(*B).ResetTimer", Method, 0, ""},
@@ -16674,6 +16713,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*B).StopTimer", Method, 0, ""},
 		{"(*B).TempDir", Method, 15, ""},
 		{"(*F).Add", Method, 18, ""},
+		{"(*F).Attr", Method, 25, ""},
 		{"(*F).Chdir", Method, 24, ""},
 		{"(*F).Cleanup", Method, 18, ""},
 		{"(*F).Context", Method, 24, ""},
@@ -16689,6 +16729,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*F).Log", Method, 18, ""},
 		{"(*F).Logf", Method, 18, ""},
 		{"(*F).Name", Method, 18, ""},
+		{"(*F).Output", Method, 25, ""},
 		{"(*F).Setenv", Method, 18, ""},
 		{"(*F).Skip", Method, 18, ""},
 		{"(*F).SkipNow", Method, 18, ""},
@@ -16697,6 +16738,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*F).TempDir", Method, 18, ""},
 		{"(*M).Run", Method, 4, ""},
 		{"(*PB).Next", Method, 3, ""},
+		{"(*T).Attr", Method, 25, ""},
 		{"(*T).Chdir", Method, 24, ""},
 		{"(*T).Cleanup", Method, 14, ""},
 		{"(*T).Context", Method, 24, ""},
@@ -16712,6 +16754,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"(*T).Log", Method, 0, ""},
 		{"(*T).Logf", Method, 0, ""},
 		{"(*T).Name", Method, 8, ""},
+		{"(*T).Output", Method, 25, ""},
 		{"(*T).Parallel", Method, 0, ""},
 		{"(*T).Run", Method, 7, ""},
 		{"(*T).Setenv", Method, 17, ""},
@@ -16834,6 +16877,10 @@ var PackageSymbols = map[string][]Symbol{
 		{"Run", Func, 22, "func(t *testing.T, newHandler func(*testing.T) slog.Handler, result func(*testing.T) map[string]any)"},
 		{"TestHandler", Func, 21, "func(h slog.Handler, results func() []map[string]any) error"},
 	},
+	"testing/synctest": {
+		{"Test", Func, 25, "func(t *testing.T, f func(*testing.T))"},
+		{"Wait", Func, 25, "func()"},
+	},
 	"text/scanner": {
 		{"(*Position).IsValid", Method, 0, ""},
 		{"(*Scanner).Init", Method, 0, ""},
@@ -17347,6 +17394,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"CaseRange.Lo", Field, 0, ""},
 		{"CaseRanges", Var, 0, ""},
 		{"Categories", Var, 0, ""},
+		{"CategoryAliases", Var, 25, ""},
 		{"Caucasian_Albanian", Var, 4, ""},
 		{"Cc", Var, 0, ""},
 		{"Cf", Var, 0, ""},
@@ -17354,6 +17402,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"Cham", Var, 0, ""},
 		{"Cherokee", Var, 0, ""},
 		{"Chorasmian", Var, 16, ""},
+		{"Cn", Var, 25, ""},
 		{"Co", Var, 0, ""},
 		{"Common", Var, 0, ""},
 		{"Coptic", Var, 0, ""},
@@ -17432,6 +17481,7 @@ var PackageSymbols = map[string][]Symbol{
 		{"Khojki", Var, 4, ""},
 		{"Khudawadi", Var, 4, ""},
 		{"L", Var, 0, ""},
+		{"LC", Var, 25, ""},
 		{"Lao", Var, 0, ""},
 		{"Latin", Var, 0, ""},
 		{"Lepcha", Var, 0, ""},
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/fx.go b/vendor/golang.org/x/tools/internal/typesinternal/fx.go
new file mode 100644
index 000000000..93acff217
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/fx.go
@@ -0,0 +1,49 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/ast"
+	"go/token"
+	"go/types"
+)
+
+// NoEffects reports whether the expression has no side effects, i.e., it
+// does not modify the memory state. This function is conservative: it may
+// return false even when the expression has no effect.
+func NoEffects(info *types.Info, expr ast.Expr) bool {
+	noEffects := true
+	ast.Inspect(expr, func(n ast.Node) bool {
+		switch v := n.(type) {
+		case nil, *ast.Ident, *ast.BasicLit, *ast.BinaryExpr, *ast.ParenExpr,
+			*ast.SelectorExpr, *ast.IndexExpr, *ast.SliceExpr, *ast.TypeAssertExpr,
+			*ast.StarExpr, *ast.CompositeLit, *ast.ArrayType, *ast.StructType,
+			*ast.MapType, *ast.InterfaceType, *ast.KeyValueExpr:
+			// No effect
+		case *ast.UnaryExpr:
+			// Channel send <-ch has effects
+			if v.Op == token.ARROW {
+				noEffects = false
+			}
+		case *ast.CallExpr:
+			// Type conversion has no effects
+			if !info.Types[v.Fun].IsType() {
+				// TODO(adonovan): Add a case for built-in functions without side
+				// effects (by using callsPureBuiltin from tools/internal/refactor/inline)
+
+				noEffects = false
+			}
+		case *ast.FuncLit:
+			// A FuncLit has no effects, but do not descend into it.
+			return false
+		default:
+			// All other expressions have effects
+			noEffects = false
+		}
+
+		return noEffects
+	})
+	return noEffects
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go b/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go
new file mode 100644
index 000000000..f2affec4f
--- /dev/null
+++ b/vendor/golang.org/x/tools/internal/typesinternal/isnamed.go
@@ -0,0 +1,71 @@
+// Copyright 2025 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package typesinternal
+
+import (
+	"go/types"
+	"slices"
+)
+
+// IsTypeNamed reports whether t is (or is an alias for) a
+// package-level defined type with the given package path and one of
+// the given names. It returns false if t is nil.
+//
+// This function avoids allocating the concatenation of "pkg.Name",
+// which is important for the performance of syntax matching.
+func IsTypeNamed(t types.Type, pkgPath string, names ...string) bool {
+	if named, ok := types.Unalias(t).(*types.Named); ok {
+		tname := named.Obj()
+		return tname != nil &&
+			IsPackageLevel(tname) &&
+			tname.Pkg().Path() == pkgPath &&
+			slices.Contains(names, tname.Name())
+	}
+	return false
+}
+
+// IsPointerToNamed reports whether t is (or is an alias for) a pointer to a
+// package-level defined type with the given package path and one of the given
+// names. It returns false if t is not a pointer type.
+func IsPointerToNamed(t types.Type, pkgPath string, names ...string) bool {
+	r := Unpointer(t)
+	if r == t {
+		return false
+	}
+	return IsTypeNamed(r, pkgPath, names...)
+}
+
+// IsFunctionNamed reports whether obj is a package-level function
+// defined in the given package and has one of the given names.
+// It returns false if obj is nil.
+//
+// This function avoids allocating the concatenation of "pkg.Name",
+// which is important for the performance of syntax matching.
+func IsFunctionNamed(obj types.Object, pkgPath string, names ...string) bool {
+	f, ok := obj.(*types.Func)
+	return ok &&
+		IsPackageLevel(obj) &&
+		f.Pkg().Path() == pkgPath &&
+		f.Type().(*types.Signature).Recv() == nil &&
+		slices.Contains(names, f.Name())
+}
+
+// IsMethodNamed reports whether obj is a method defined on a
+// package-level type with the given package and type name, and has
+// one of the given names. It returns false if obj is nil.
+//
+// This function avoids allocating the concatenation of "pkg.TypeName.Name",
+// which is important for the performance of syntax matching.
+func IsMethodNamed(obj types.Object, pkgPath string, typeName string, names ...string) bool {
+	if fn, ok := obj.(*types.Func); ok {
+		if recv := fn.Type().(*types.Signature).Recv(); recv != nil {
+			_, T := ReceiverNamed(recv)
+			return T != nil &&
+				IsTypeNamed(T, pkgPath, typeName) &&
+				slices.Contains(names, fn.Name())
+		}
+	}
+	return false
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go b/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go
index b64f714eb..64f47919f 100644
--- a/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go
+++ b/vendor/golang.org/x/tools/internal/typesinternal/qualifier.go
@@ -15,6 +15,14 @@ import (
 // file.
 // If the same package is imported multiple times, the last appearance is
 // recorded.
+//
+// TODO(adonovan): this function ignores the effect of shadowing. It
+// should accept a [token.Pos] and a [types.Info] and compute only the
+// set of imports that are not shadowed at that point, analogous to
+// [analysisinternal.AddImport]. It could also compute (as a side
+// effect) the set of additional imports required to ensure that there
+// is an accessible import for each necessary package, making it
+// converge even more closely with AddImport.
 func FileQualifier(f *ast.File, pkg *types.Package) types.Qualifier {
 	// Construct mapping of import paths to their defined names.
 	// It is only necessary to look at renaming imports.
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/types.go b/vendor/golang.org/x/tools/internal/typesinternal/types.go
index a5cd7e8db..fef74a785 100644
--- a/vendor/golang.org/x/tools/internal/typesinternal/types.go
+++ b/vendor/golang.org/x/tools/internal/typesinternal/types.go
@@ -2,8 +2,20 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// Package typesinternal provides access to internal go/types APIs that are not
-// yet exported.
+// Package typesinternal provides helpful operators for dealing with
+// go/types:
+//
+//   - operators for querying typed syntax trees (e.g. [Imports], [IsFunctionNamed]);
+//   - functions for converting types to strings or syntax (e.g. [TypeExpr], FileQualifier]);
+//   - helpers for working with the [go/types] API (e.g. [NewTypesInfo]);
+//   - access to internal go/types APIs that are not yet
+//     exported (e.g. [SetUsesCgo], [ErrorCodeStartEnd], [VarKind]); and
+//   - common algorithms related to types (e.g. [TooNewStdSymbols]).
+//
+// See also:
+//   - [golang.org/x/tools/internal/astutil], for operations on untyped syntax;
+//   - [golang.org/x/tools/internal/analysisinernal], for helpers for analyzers;
+//   - [golang.org/x/tools/internal/refactor], for operators to compute text edits.
 package typesinternal
 
 import (
@@ -13,6 +25,7 @@ import (
 	"reflect"
 	"unsafe"
 
+	"golang.org/x/tools/go/ast/inspector"
 	"golang.org/x/tools/internal/aliases"
 )
 
@@ -60,6 +73,9 @@ func ErrorCodeStartEnd(err types.Error) (code ErrorCode, start, end token.Pos, o
 // which is often excessive.)
 //
 // If pkg is nil, it is equivalent to [*types.Package.Name].
+//
+// TODO(adonovan): all uses of this with TypeString should be
+// eliminated when https://go.dev/issues/75604 is resolved.
 func NameRelativeTo(pkg *types.Package) types.Qualifier {
 	return func(other *types.Package) string {
 		if pkg != nil && pkg == other {
@@ -153,3 +169,31 @@ func NewTypesInfo() *types.Info {
 		FileVersions: map[*ast.File]string{},
 	}
 }
+
+// EnclosingScope returns the innermost block logically enclosing the cursor.
+func EnclosingScope(info *types.Info, cur inspector.Cursor) *types.Scope {
+	for cur := range cur.Enclosing() {
+		n := cur.Node()
+		// A function's Scope is associated with its FuncType.
+		switch f := n.(type) {
+		case *ast.FuncDecl:
+			n = f.Type
+		case *ast.FuncLit:
+			n = f.Type
+		}
+		if b := info.Scopes[n]; b != nil {
+			return b
+		}
+	}
+	panic("no Scope for *ast.File")
+}
+
+// Imports reports whether path is imported by pkg.
+func Imports(pkg *types.Package, path string) bool {
+	for _, imp := range pkg.Imports() {
+		if imp.Path() == path {
+			return true
+		}
+	}
+	return false
+}
diff --git a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go b/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go
index d272949c1..453bba2ad 100644
--- a/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go
+++ b/vendor/golang.org/x/tools/internal/typesinternal/zerovalue.go
@@ -204,23 +204,12 @@ func ZeroExpr(t types.Type, qual types.Qualifier) (_ ast.Expr, isValid bool) {
 	}
 }
 
-// IsZeroExpr uses simple syntactic heuristics to report whether expr
-// is a obvious zero value, such as 0, "", nil, or false.
-// It cannot do better without type information.
-func IsZeroExpr(expr ast.Expr) bool {
-	switch e := expr.(type) {
-	case *ast.BasicLit:
-		return e.Value == "0" || e.Value == `""`
-	case *ast.Ident:
-		return e.Name == "nil" || e.Name == "false"
-	default:
-		return false
-	}
-}
-
 // TypeExpr returns syntax for the specified type. References to named types
 // are qualified by an appropriate (optional) qualifier function.
 // It may panic for types such as Tuple or Union.
+//
+// See also https://go.dev/issues/75604, which will provide a robust
+// Type-to-valid-Go-syntax formatter.
 func TypeExpr(t types.Type, qual types.Qualifier) ast.Expr {
 	switch t := t.(type) {
 	case *types.Basic:
diff --git a/vendor/modules.txt b/vendor/modules.txt
index bd3d4c848..fc02a8b7b 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -190,10 +190,10 @@ github.com/josharian/intern
 # github.com/json-iterator/go v1.1.12
 ## explicit; go 1.12
 github.com/json-iterator/go
-# github.com/kubeflow/mpi-operator v0.6.0
-## explicit; go 1.23
+# github.com/kubeflow/mpi-operator v0.7.0
+## explicit; go 1.25.0
 github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1
-# github.com/kubeflow/trainer/v2 v2.1.0-rc.0
+# github.com/kubeflow/trainer/v2 v2.1.0
 ## explicit; go 1.24.0
 github.com/kubeflow/trainer/v2/pkg/apis/trainer/v1alpha1
 github.com/kubeflow/trainer/v2/pkg/apply
@@ -253,12 +253,13 @@ github.com/munnerz/goautoneg
 # github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
 ## explicit
 github.com/mxk/go-flowrate/flowrate
-# github.com/onsi/ginkgo/v2 v2.27.1
+# github.com/onsi/ginkgo/v2 v2.27.2
 ## explicit; go 1.23.0
 github.com/onsi/ginkgo/v2
 github.com/onsi/ginkgo/v2/config
 github.com/onsi/ginkgo/v2/formatter
 github.com/onsi/ginkgo/v2/ginkgo
+github.com/onsi/ginkgo/v2/ginkgo/automaxprocs
 github.com/onsi/ginkgo/v2/ginkgo/build
 github.com/onsi/ginkgo/v2/ginkgo/command
 github.com/onsi/ginkgo/v2/ginkgo/generators
@@ -332,10 +333,12 @@ github.com/prometheus/common/model
 github.com/prometheus/procfs
 github.com/prometheus/procfs/internal/fs
 github.com/prometheus/procfs/internal/util
-# github.com/ray-project/kuberay/ray-operator v1.4.2
+# github.com/ray-project/kuberay/ray-operator v1.5.0
 ## explicit; go 1.24.0
 github.com/ray-project/kuberay/ray-operator/apis/ray/v1
 github.com/ray-project/kuberay/ray-operator/controllers/ray/utils
+github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/dashboardclient
+github.com/ray-project/kuberay/ray-operator/controllers/ray/utils/types
 github.com/ray-project/kuberay/ray-operator/pkg/features
 # github.com/russross/blackfriday/v2 v2.1.0
 ## explicit
@@ -453,12 +456,6 @@ go.opentelemetry.io/proto/otlp/trace/v1
 # go.uber.org/atomic v1.11.0
 ## explicit; go 1.18
 go.uber.org/atomic
-# go.uber.org/automaxprocs v1.6.0
-## explicit; go 1.20
-go.uber.org/automaxprocs
-go.uber.org/automaxprocs/internal/cgroups
-go.uber.org/automaxprocs/internal/runtime
-go.uber.org/automaxprocs/maxprocs
 # go.uber.org/mock v0.6.0
 ## explicit; go 1.23.0
 go.uber.org/mock/gomock
@@ -477,13 +474,13 @@ go.uber.org/zap/internal/pool
 go.uber.org/zap/internal/stacktrace
 go.uber.org/zap/zapcore
 go.uber.org/zap/zapgrpc
-# go.yaml.in/yaml/v2 v2.4.2
+# go.yaml.in/yaml/v2 v2.4.3
 ## explicit; go 1.15
 go.yaml.in/yaml/v2
 # go.yaml.in/yaml/v3 v3.0.4
 ## explicit; go 1.16
 go.yaml.in/yaml/v3
-# golang.org/x/crypto v0.42.0
+# golang.org/x/crypto v0.43.0
 ## explicit; go 1.24.0
 golang.org/x/crypto/blowfish
 golang.org/x/crypto/chacha20
@@ -500,12 +497,12 @@ golang.org/x/crypto/ssh/internal/bcrypt_pbkdf
 # golang.org/x/exp v0.0.0-20250718183923-645b1fa84792
 ## explicit; go 1.23.0
 golang.org/x/exp/slices
-# golang.org/x/mod v0.27.0
-## explicit; go 1.23.0
+# golang.org/x/mod v0.29.0
+## explicit; go 1.24.0
 golang.org/x/mod/internal/lazyregexp
 golang.org/x/mod/module
 golang.org/x/mod/semver
-# golang.org/x/net v0.44.0
+# golang.org/x/net v0.46.0
 ## explicit; go 1.24.0
 golang.org/x/net/context
 golang.org/x/net/html
@@ -525,21 +522,21 @@ golang.org/x/net/websocket
 ## explicit; go 1.24.0
 golang.org/x/oauth2
 golang.org/x/oauth2/internal
-# golang.org/x/sync v0.17.0
+# golang.org/x/sync v0.18.0
 ## explicit; go 1.24.0
 golang.org/x/sync/errgroup
 golang.org/x/sync/singleflight
-# golang.org/x/sys v0.36.0
+# golang.org/x/sys v0.37.0
 ## explicit; go 1.24.0
 golang.org/x/sys/cpu
 golang.org/x/sys/plan9
 golang.org/x/sys/unix
 golang.org/x/sys/windows
 golang.org/x/sys/windows/registry
-# golang.org/x/term v0.35.0
+# golang.org/x/term v0.36.0
 ## explicit; go 1.24.0
 golang.org/x/term
-# golang.org/x/text v0.29.0
+# golang.org/x/text v0.30.0
 ## explicit; go 1.24.0
 golang.org/x/text/cases
 golang.org/x/text/encoding
@@ -570,11 +567,11 @@ golang.org/x/text/secure/bidirule
 golang.org/x/text/transform
 golang.org/x/text/unicode/bidi
 golang.org/x/text/unicode/norm
-# golang.org/x/time v0.13.0
+# golang.org/x/time v0.14.0
 ## explicit; go 1.24.0
 golang.org/x/time/rate
-# golang.org/x/tools v0.36.0
-## explicit; go 1.23.0
+# golang.org/x/tools v0.38.0
+## explicit; go 1.24.0
 golang.org/x/tools/cover
 golang.org/x/tools/go/ast/astutil
 golang.org/x/tools/go/ast/edge
@@ -1564,7 +1561,7 @@ k8s.io/kubectl/pkg/validation
 k8s.io/metrics/pkg/apis/metrics
 k8s.io/metrics/pkg/apis/metrics/install
 k8s.io/metrics/pkg/apis/metrics/v1beta1
-# k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d
+# k8s.io/utils v0.0.0-20251002143259-bc988d571ff4
 ## explicit; go 1.18
 k8s.io/utils/buffer
 k8s.io/utils/clock
@@ -1585,7 +1582,7 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/client/metrics
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client/pkg/common/metrics
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client/proto/client
-# sigs.k8s.io/controller-runtime v0.22.3
+# sigs.k8s.io/controller-runtime v0.22.4
 ## explicit; go 1.24.0
 sigs.k8s.io/controller-runtime
 sigs.k8s.io/controller-runtime/pkg/builder
@@ -1741,8 +1738,8 @@ sigs.k8s.io/lws/api/leaderworkerset/v1
 ## explicit; go 1.18
 sigs.k8s.io/randfill
 sigs.k8s.io/randfill/bytesource
-# sigs.k8s.io/scheduler-plugins v0.31.8
-## explicit; go 1.22.0
+# sigs.k8s.io/scheduler-plugins v0.34.1-devel
+## explicit; go 1.24.0
 sigs.k8s.io/scheduler-plugins/apis/scheduling
 sigs.k8s.io/scheduler-plugins/apis/scheduling/v1alpha1
 sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1
@@ -1757,8 +1754,8 @@ sigs.k8s.io/structured-merge-diff/v6/value
 ## explicit; go 1.22
 sigs.k8s.io/yaml
 sigs.k8s.io/yaml/kyaml
-# volcano.sh/apis v1.12.2
-## explicit; go 1.23.0
+# volcano.sh/apis v1.13.1-0.20251028070205-46d20c0699e7
+## explicit; go 1.24.0
 volcano.sh/apis/pkg/apis/scheduling
 volcano.sh/apis/pkg/apis/scheduling/v1beta1
 volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
index a7e491855..a94ec6cc3 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/cache/cache.go
@@ -308,6 +308,42 @@ type ByObject struct {
 	//
 	// Defaults to true.
 	EnableWatchBookmarks *bool
+
+	// SyncPeriod determines the minimum frequency at which watched resources are
+	// reconciled. A lower period will correct entropy more quickly, but reduce
+	// responsiveness to change if there are many watched resources. Change this
+	// value only if you know what you are doing. Defaults to 10 hours if unset.
+	// there will a 10 percent jitter between the SyncPeriod of all controllers
+	// so that all controllers will not send list requests simultaneously.
+	//
+	// This applies to all controllers.
+	//
+	// A period sync happens for two reasons:
+	// 1. To insure against a bug in the controller that causes an object to not
+	// be requeued, when it otherwise should be requeued.
+	// 2. To insure against an unknown bug in controller-runtime, or its dependencies,
+	// that causes an object to not be requeued, when it otherwise should be
+	// requeued, or to be removed from the queue, when it otherwise should not
+	// be removed.
+	//
+	// If you want
+	// 1. to insure against missed watch events, or
+	// 2. to poll services that cannot be watched,
+	// then we recommend that, instead of changing the default period, the
+	// controller requeue, with a constant duration `t`, whenever the controller
+	// is "done" with an object, and would otherwise not requeue it, i.e., we
+	// recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`,
+	// instead of `reconcile.Result{}`.
+	//
+	// SyncPeriod will locally trigger an artificial Update event with the same
+	// object in both ObjectOld and ObjectNew for everything that is in the
+	// cache.
+	//
+	// Predicates or Handlers that expect ObjectOld and ObjectNew to be different
+	// (such as GenerationChangedPredicate) will filter out this event, preventing
+	// it from triggering a reconciliation.
+	// SyncPeriod does not sync between the local cache and the server.
+	SyncPeriod *time.Duration
 }
 
 // Config describes all potential options for a given watch.
@@ -343,6 +379,42 @@ type Config struct {
 	//
 	// Defaults to true.
 	EnableWatchBookmarks *bool
+
+	// SyncPeriod determines the minimum frequency at which watched resources are
+	// reconciled. A lower period will correct entropy more quickly, but reduce
+	// responsiveness to change if there are many watched resources. Change this
+	// value only if you know what you are doing. Defaults to 10 hours if unset.
+	// there will a 10 percent jitter between the SyncPeriod of all controllers
+	// so that all controllers will not send list requests simultaneously.
+	//
+	// This applies to all controllers.
+	//
+	// A period sync happens for two reasons:
+	// 1. To insure against a bug in the controller that causes an object to not
+	// be requeued, when it otherwise should be requeued.
+	// 2. To insure against an unknown bug in controller-runtime, or its dependencies,
+	// that causes an object to not be requeued, when it otherwise should be
+	// requeued, or to be removed from the queue, when it otherwise should not
+	// be removed.
+	//
+	// If you want
+	// 1. to insure against missed watch events, or
+	// 2. to poll services that cannot be watched,
+	// then we recommend that, instead of changing the default period, the
+	// controller requeue, with a constant duration `t`, whenever the controller
+	// is "done" with an object, and would otherwise not requeue it, i.e., we
+	// recommend the `Reconcile` function return `reconcile.Result{RequeueAfter: t}`,
+	// instead of `reconcile.Result{}`.
+	//
+	// SyncPeriod will locally trigger an artificial Update event with the same
+	// object in both ObjectOld and ObjectNew for everything that is in the
+	// cache.
+	//
+	// Predicates or Handlers that expect ObjectOld and ObjectNew to be different
+	// (such as GenerationChangedPredicate) will filter out this event, preventing
+	// it from triggering a reconciliation.
+	// SyncPeriod does not sync between the local cache and the server.
+	SyncPeriod *time.Duration
 }
 
 // NewCacheFunc - Function for creating a new cache from the options and a rest config.
@@ -413,6 +485,7 @@ func optionDefaultsToConfig(opts *Options) Config {
 		Transform:             opts.DefaultTransform,
 		UnsafeDisableDeepCopy: opts.DefaultUnsafeDisableDeepCopy,
 		EnableWatchBookmarks:  opts.DefaultEnableWatchBookmarks,
+		SyncPeriod:            opts.SyncPeriod,
 	}
 }
 
@@ -423,6 +496,7 @@ func byObjectToConfig(byObject ByObject) Config {
 		Transform:             byObject.Transform,
 		UnsafeDisableDeepCopy: byObject.UnsafeDisableDeepCopy,
 		EnableWatchBookmarks:  byObject.EnableWatchBookmarks,
+		SyncPeriod:            byObject.SyncPeriod,
 	}
 }
 
@@ -436,7 +510,7 @@ func newCache(restConfig *rest.Config, opts Options) newCacheFunc {
 				HTTPClient:   opts.HTTPClient,
 				Scheme:       opts.Scheme,
 				Mapper:       opts.Mapper,
-				ResyncPeriod: *opts.SyncPeriod,
+				ResyncPeriod: ptr.Deref(config.SyncPeriod, defaultSyncPeriod),
 				Namespace:    namespace,
 				Selector: internal.Selector{
 					Label: config.LabelSelector,
@@ -534,6 +608,7 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
 			byObject.Transform = defaultedConfig.Transform
 			byObject.UnsafeDisableDeepCopy = defaultedConfig.UnsafeDisableDeepCopy
 			byObject.EnableWatchBookmarks = defaultedConfig.EnableWatchBookmarks
+			byObject.SyncPeriod = defaultedConfig.SyncPeriod
 		}
 
 		opts.ByObject[obj] = byObject
@@ -555,10 +630,6 @@ func defaultOpts(config *rest.Config, opts Options) (Options, error) {
 		opts.DefaultNamespaces[namespace] = cfg
 	}
 
-	// Default the resync period to 10 hours if unset
-	if opts.SyncPeriod == nil {
-		opts.SyncPeriod = &defaultSyncPeriod
-	}
 	return opts, nil
 }
 
@@ -578,6 +649,9 @@ func defaultConfig(toDefault, defaultFrom Config) Config {
 	if toDefault.EnableWatchBookmarks == nil {
 		toDefault.EnableWatchBookmarks = defaultFrom.EnableWatchBookmarks
 	}
+	if toDefault.SyncPeriod == nil {
+		toDefault.SyncPeriod = defaultFrom.SyncPeriod
+	}
 	return toDefault
 }
 
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go b/vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go
index cacba4a9c..d4223eda2 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/client/namespaced_client.go
@@ -213,7 +213,12 @@ func (n *namespacedClient) Get(ctx context.Context, key ObjectKey, obj Object, o
 
 // List implements client.Client.
 func (n *namespacedClient) List(ctx context.Context, obj ObjectList, opts ...ListOption) error {
-	if n.namespace != "" {
+	isNamespaceScoped, err := n.IsObjectNamespaced(obj)
+	if err != nil {
+		return fmt.Errorf("error finding the scope of the object: %w", err)
+	}
+
+	if isNamespaceScoped && n.namespace != "" {
 		opts = append(opts, InNamespace(n.namespace))
 	}
 	return n.client.List(ctx, obj, opts...)
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue/priorityqueue.go b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue/priorityqueue.go
index 98df84c56..71363f0d1 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue/priorityqueue.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/controller/priorityqueue/priorityqueue.go
@@ -124,8 +124,8 @@ type priorityqueue[T comparable] struct {
 	get chan item[T]
 
 	// waiters is the number of routines blocked in Get, we use it to determine
-	// if we can push items.
-	waiters atomic.Int64
+	// if we can push items. Every manipulation has to be protected with the lock.
+	waiters int64
 
 	// Configurable for testing
 	now  func() time.Time
@@ -269,7 +269,7 @@ func (w *priorityqueue[T]) spin() {
 						}
 					}
 
-					if w.waiters.Load() == 0 {
+					if w.waiters == 0 {
 						// Have to keep iterating here to ensure we update metrics
 						// for further items that became ready and set nextReady.
 						return true
@@ -277,7 +277,7 @@ func (w *priorityqueue[T]) spin() {
 
 					w.metrics.get(item.Key, item.Priority)
 					w.locked.Insert(item.Key)
-					w.waiters.Add(-1)
+					w.waiters--
 					delete(w.items, item.Key)
 					toDelete = append(toDelete, item)
 					w.becameReady.Delete(item.Key)
@@ -316,7 +316,9 @@ func (w *priorityqueue[T]) GetWithPriority() (_ T, priority int, shutdown bool)
 		return zero, 0, true
 	}
 
-	w.waiters.Add(1)
+	w.lock.Lock()
+	w.waiters++
+	w.lock.Unlock()
 
 	w.notifyItemOrWaiterAdded()
 
diff --git a/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/elasticquota.go b/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/elasticquota.go
index 89f2caa6f..587b88771 100644
--- a/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/elasticquota.go
+++ b/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/elasticquota.go
@@ -43,12 +43,13 @@ func ElasticQuota(name, namespace string) *ElasticQuotaApplyConfiguration {
 	b.WithAPIVersion("scheduling.x-k8s.io/v1alpha1")
 	return b
 }
+func (b ElasticQuotaApplyConfiguration) IsApplyConfiguration() {}
 
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Kind field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithKind(value string) *ElasticQuotaApplyConfiguration {
-	b.Kind = &value
+	b.TypeMetaApplyConfiguration.Kind = &value
 	return b
 }
 
@@ -56,7 +57,7 @@ func (b *ElasticQuotaApplyConfiguration) WithKind(value string) *ElasticQuotaApp
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the APIVersion field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithAPIVersion(value string) *ElasticQuotaApplyConfiguration {
-	b.APIVersion = &value
+	b.TypeMetaApplyConfiguration.APIVersion = &value
 	return b
 }
 
@@ -65,7 +66,7 @@ func (b *ElasticQuotaApplyConfiguration) WithAPIVersion(value string) *ElasticQu
 // If called multiple times, the Name field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithName(value string) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.Name = &value
+	b.ObjectMetaApplyConfiguration.Name = &value
 	return b
 }
 
@@ -74,7 +75,7 @@ func (b *ElasticQuotaApplyConfiguration) WithName(value string) *ElasticQuotaApp
 // If called multiple times, the GenerateName field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithGenerateName(value string) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.GenerateName = &value
+	b.ObjectMetaApplyConfiguration.GenerateName = &value
 	return b
 }
 
@@ -83,7 +84,7 @@ func (b *ElasticQuotaApplyConfiguration) WithGenerateName(value string) *Elastic
 // If called multiple times, the Namespace field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithNamespace(value string) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.Namespace = &value
+	b.ObjectMetaApplyConfiguration.Namespace = &value
 	return b
 }
 
@@ -92,7 +93,7 @@ func (b *ElasticQuotaApplyConfiguration) WithNamespace(value string) *ElasticQuo
 // If called multiple times, the UID field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithUID(value types.UID) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.UID = &value
+	b.ObjectMetaApplyConfiguration.UID = &value
 	return b
 }
 
@@ -101,7 +102,7 @@ func (b *ElasticQuotaApplyConfiguration) WithUID(value types.UID) *ElasticQuotaA
 // If called multiple times, the ResourceVersion field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithResourceVersion(value string) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.ResourceVersion = &value
+	b.ObjectMetaApplyConfiguration.ResourceVersion = &value
 	return b
 }
 
@@ -110,7 +111,7 @@ func (b *ElasticQuotaApplyConfiguration) WithResourceVersion(value string) *Elas
 // If called multiple times, the Generation field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithGeneration(value int64) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.Generation = &value
+	b.ObjectMetaApplyConfiguration.Generation = &value
 	return b
 }
 
@@ -119,7 +120,7 @@ func (b *ElasticQuotaApplyConfiguration) WithGeneration(value int64) *ElasticQuo
 // If called multiple times, the CreationTimestamp field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithCreationTimestamp(value metav1.Time) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.CreationTimestamp = &value
+	b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
 	return b
 }
 
@@ -128,7 +129,7 @@ func (b *ElasticQuotaApplyConfiguration) WithCreationTimestamp(value metav1.Time
 // If called multiple times, the DeletionTimestamp field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.DeletionTimestamp = &value
+	b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
 	return b
 }
 
@@ -137,7 +138,7 @@ func (b *ElasticQuotaApplyConfiguration) WithDeletionTimestamp(value metav1.Time
 // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call.
 func (b *ElasticQuotaApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.DeletionGracePeriodSeconds = &value
+	b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
 	return b
 }
 
@@ -147,11 +148,11 @@ func (b *ElasticQuotaApplyConfiguration) WithDeletionGracePeriodSeconds(value in
 // overwriting an existing map entries in Labels field with the same key.
 func (b *ElasticQuotaApplyConfiguration) WithLabels(entries map[string]string) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	if b.Labels == nil && len(entries) > 0 {
-		b.Labels = make(map[string]string, len(entries))
+	if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
+		b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
 	}
 	for k, v := range entries {
-		b.Labels[k] = v
+		b.ObjectMetaApplyConfiguration.Labels[k] = v
 	}
 	return b
 }
@@ -162,11 +163,11 @@ func (b *ElasticQuotaApplyConfiguration) WithLabels(entries map[string]string) *
 // overwriting an existing map entries in Annotations field with the same key.
 func (b *ElasticQuotaApplyConfiguration) WithAnnotations(entries map[string]string) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	if b.Annotations == nil && len(entries) > 0 {
-		b.Annotations = make(map[string]string, len(entries))
+	if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
+		b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
 	}
 	for k, v := range entries {
-		b.Annotations[k] = v
+		b.ObjectMetaApplyConfiguration.Annotations[k] = v
 	}
 	return b
 }
@@ -180,7 +181,7 @@ func (b *ElasticQuotaApplyConfiguration) WithOwnerReferences(values ...*v1.Owner
 		if values[i] == nil {
 			panic("nil value passed to WithOwnerReferences")
 		}
-		b.OwnerReferences = append(b.OwnerReferences, *values[i])
+		b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
 	}
 	return b
 }
@@ -191,7 +192,7 @@ func (b *ElasticQuotaApplyConfiguration) WithOwnerReferences(values ...*v1.Owner
 func (b *ElasticQuotaApplyConfiguration) WithFinalizers(values ...string) *ElasticQuotaApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
 	for i := range values {
-		b.Finalizers = append(b.Finalizers, values[i])
+		b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
 	}
 	return b
 }
@@ -218,8 +219,24 @@ func (b *ElasticQuotaApplyConfiguration) WithStatus(value *ElasticQuotaStatusApp
 	return b
 }
 
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *ElasticQuotaApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *ElasticQuotaApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
 // GetName retrieves the value of the Name field in the declarative configuration.
 func (b *ElasticQuotaApplyConfiguration) GetName() *string {
 	b.ensureObjectMetaApplyConfigurationExists()
-	return b.Name
+	return b.ObjectMetaApplyConfiguration.Name
+}
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *ElasticQuotaApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
 }
diff --git a/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/podgroup.go b/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/podgroup.go
index 623ff2b5a..3d465355d 100644
--- a/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/podgroup.go
+++ b/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/podgroup.go
@@ -43,12 +43,13 @@ func PodGroup(name, namespace string) *PodGroupApplyConfiguration {
 	b.WithAPIVersion("scheduling.x-k8s.io/v1alpha1")
 	return b
 }
+func (b PodGroupApplyConfiguration) IsApplyConfiguration() {}
 
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Kind field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithKind(value string) *PodGroupApplyConfiguration {
-	b.Kind = &value
+	b.TypeMetaApplyConfiguration.Kind = &value
 	return b
 }
 
@@ -56,7 +57,7 @@ func (b *PodGroupApplyConfiguration) WithKind(value string) *PodGroupApplyConfig
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the APIVersion field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithAPIVersion(value string) *PodGroupApplyConfiguration {
-	b.APIVersion = &value
+	b.TypeMetaApplyConfiguration.APIVersion = &value
 	return b
 }
 
@@ -65,7 +66,7 @@ func (b *PodGroupApplyConfiguration) WithAPIVersion(value string) *PodGroupApply
 // If called multiple times, the Name field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithName(value string) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.Name = &value
+	b.ObjectMetaApplyConfiguration.Name = &value
 	return b
 }
 
@@ -74,7 +75,7 @@ func (b *PodGroupApplyConfiguration) WithName(value string) *PodGroupApplyConfig
 // If called multiple times, the GenerateName field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithGenerateName(value string) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.GenerateName = &value
+	b.ObjectMetaApplyConfiguration.GenerateName = &value
 	return b
 }
 
@@ -83,7 +84,7 @@ func (b *PodGroupApplyConfiguration) WithGenerateName(value string) *PodGroupApp
 // If called multiple times, the Namespace field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithNamespace(value string) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.Namespace = &value
+	b.ObjectMetaApplyConfiguration.Namespace = &value
 	return b
 }
 
@@ -92,7 +93,7 @@ func (b *PodGroupApplyConfiguration) WithNamespace(value string) *PodGroupApplyC
 // If called multiple times, the UID field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithUID(value types.UID) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.UID = &value
+	b.ObjectMetaApplyConfiguration.UID = &value
 	return b
 }
 
@@ -101,7 +102,7 @@ func (b *PodGroupApplyConfiguration) WithUID(value types.UID) *PodGroupApplyConf
 // If called multiple times, the ResourceVersion field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithResourceVersion(value string) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.ResourceVersion = &value
+	b.ObjectMetaApplyConfiguration.ResourceVersion = &value
 	return b
 }
 
@@ -110,7 +111,7 @@ func (b *PodGroupApplyConfiguration) WithResourceVersion(value string) *PodGroup
 // If called multiple times, the Generation field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithGeneration(value int64) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.Generation = &value
+	b.ObjectMetaApplyConfiguration.Generation = &value
 	return b
 }
 
@@ -119,7 +120,7 @@ func (b *PodGroupApplyConfiguration) WithGeneration(value int64) *PodGroupApplyC
 // If called multiple times, the CreationTimestamp field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithCreationTimestamp(value metav1.Time) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.CreationTimestamp = &value
+	b.ObjectMetaApplyConfiguration.CreationTimestamp = &value
 	return b
 }
 
@@ -128,7 +129,7 @@ func (b *PodGroupApplyConfiguration) WithCreationTimestamp(value metav1.Time) *P
 // If called multiple times, the DeletionTimestamp field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.DeletionTimestamp = &value
+	b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value
 	return b
 }
 
@@ -137,7 +138,7 @@ func (b *PodGroupApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *P
 // If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call.
 func (b *PodGroupApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	b.DeletionGracePeriodSeconds = &value
+	b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value
 	return b
 }
 
@@ -147,11 +148,11 @@ func (b *PodGroupApplyConfiguration) WithDeletionGracePeriodSeconds(value int64)
 // overwriting an existing map entries in Labels field with the same key.
 func (b *PodGroupApplyConfiguration) WithLabels(entries map[string]string) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	if b.Labels == nil && len(entries) > 0 {
-		b.Labels = make(map[string]string, len(entries))
+	if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 {
+		b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries))
 	}
 	for k, v := range entries {
-		b.Labels[k] = v
+		b.ObjectMetaApplyConfiguration.Labels[k] = v
 	}
 	return b
 }
@@ -162,11 +163,11 @@ func (b *PodGroupApplyConfiguration) WithLabels(entries map[string]string) *PodG
 // overwriting an existing map entries in Annotations field with the same key.
 func (b *PodGroupApplyConfiguration) WithAnnotations(entries map[string]string) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
-	if b.Annotations == nil && len(entries) > 0 {
-		b.Annotations = make(map[string]string, len(entries))
+	if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 {
+		b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries))
 	}
 	for k, v := range entries {
-		b.Annotations[k] = v
+		b.ObjectMetaApplyConfiguration.Annotations[k] = v
 	}
 	return b
 }
@@ -180,7 +181,7 @@ func (b *PodGroupApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerRefe
 		if values[i] == nil {
 			panic("nil value passed to WithOwnerReferences")
 		}
-		b.OwnerReferences = append(b.OwnerReferences, *values[i])
+		b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i])
 	}
 	return b
 }
@@ -191,7 +192,7 @@ func (b *PodGroupApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerRefe
 func (b *PodGroupApplyConfiguration) WithFinalizers(values ...string) *PodGroupApplyConfiguration {
 	b.ensureObjectMetaApplyConfigurationExists()
 	for i := range values {
-		b.Finalizers = append(b.Finalizers, values[i])
+		b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i])
 	}
 	return b
 }
@@ -218,8 +219,24 @@ func (b *PodGroupApplyConfiguration) WithStatus(value *PodGroupStatusApplyConfig
 	return b
 }
 
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *PodGroupApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *PodGroupApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
 // GetName retrieves the value of the Name field in the declarative configuration.
 func (b *PodGroupApplyConfiguration) GetName() *string {
 	b.ensureObjectMetaApplyConfigurationExists()
-	return b.Name
+	return b.ObjectMetaApplyConfiguration.Name
+}
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *PodGroupApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
 }
diff --git a/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/podgroupstatus.go b/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/podgroupstatus.go
index 910b3422a..5627695d8 100644
--- a/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/podgroupstatus.go
+++ b/vendor/sigs.k8s.io/scheduler-plugins/pkg/generated/applyconfiguration/scheduling/v1alpha1/podgroupstatus.go
@@ -20,18 +20,18 @@ package v1alpha1
 
 import (
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	v1alpha1 "sigs.k8s.io/scheduler-plugins/apis/scheduling/v1alpha1"
+	schedulingv1alpha1 "sigs.k8s.io/scheduler-plugins/apis/scheduling/v1alpha1"
 )
 
 // PodGroupStatusApplyConfiguration represents a declarative configuration of the PodGroupStatus type for use
 // with apply.
 type PodGroupStatusApplyConfiguration struct {
-	Phase             *v1alpha1.PodGroupPhase `json:"phase,omitempty"`
-	OccupiedBy        *string                 `json:"occupiedBy,omitempty"`
-	Running           *int32                  `json:"running,omitempty"`
-	Succeeded         *int32                  `json:"succeeded,omitempty"`
-	Failed            *int32                  `json:"failed,omitempty"`
-	ScheduleStartTime *v1.Time                `json:"scheduleStartTime,omitempty"`
+	Phase             *schedulingv1alpha1.PodGroupPhase `json:"phase,omitempty"`
+	OccupiedBy        *string                           `json:"occupiedBy,omitempty"`
+	Running           *int32                            `json:"running,omitempty"`
+	Succeeded         *int32                            `json:"succeeded,omitempty"`
+	Failed            *int32                            `json:"failed,omitempty"`
+	ScheduleStartTime *v1.Time                          `json:"scheduleStartTime,omitempty"`
 }
 
 // PodGroupStatusApplyConfiguration constructs a declarative configuration of the PodGroupStatus type for use with
@@ -43,7 +43,7 @@ func PodGroupStatus() *PodGroupStatusApplyConfiguration {
 // WithPhase sets the Phase field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Phase field is set to the value of the last call.
-func (b *PodGroupStatusApplyConfiguration) WithPhase(value v1alpha1.PodGroupPhase) *PodGroupStatusApplyConfiguration {
+func (b *PodGroupStatusApplyConfiguration) WithPhase(value schedulingv1alpha1.PodGroupPhase) *PodGroupStatusApplyConfiguration {
 	b.Phase = &value
 	return b
 }
diff --git a/vendor/volcano.sh/apis/pkg/apis/scheduling/types.go b/vendor/volcano.sh/apis/pkg/apis/scheduling/types.go
index d275d21b2..0d5993d69 100644
--- a/vendor/volcano.sh/apis/pkg/apis/scheduling/types.go
+++ b/vendor/volcano.sh/apis/pkg/apis/scheduling/types.go
@@ -359,8 +359,6 @@ type QueueSpec struct {
 	Weight     int32
 	Capability v1.ResourceList
 
-	// Depreicated: replaced by status.State
-	State QueueState
 	// Reclaimable indicate whether the queue can be reclaimed by other queue
 	Reclaimable *bool
 
diff --git a/vendor/volcano.sh/apis/pkg/apis/scheduling/v1beta1/conversion.go b/vendor/volcano.sh/apis/pkg/apis/scheduling/v1beta1/conversion.go
deleted file mode 100644
index e903517bd..000000000
--- a/vendor/volcano.sh/apis/pkg/apis/scheduling/v1beta1/conversion.go
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-Copyright 2020 The Volcano Authors.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package v1beta1
-
-import (
-	unsafe "unsafe"
-
-	v1 "k8s.io/api/core/v1"
-	conversion "k8s.io/apimachinery/pkg/conversion"
-	scheduling "volcano.sh/apis/pkg/apis/scheduling"
-)
-
-func Convert_scheduling_QueueSpec_To_v1beta1_QueueSpec(in *scheduling.QueueSpec, out *QueueSpec, s conversion.Scope) error {
-	out.Weight = in.Weight
-	out.Capability = *(*v1.ResourceList)(unsafe.Pointer(&in.Capability))
-	out.Reclaimable = (*bool)(unsafe.Pointer(in.Reclaimable))
-	out.Parent = in.Parent
-
-	return nil
-}
diff --git a/vendor/volcano.sh/apis/pkg/apis/scheduling/v1beta1/zz_generated.conversion.go b/vendor/volcano.sh/apis/pkg/apis/scheduling/v1beta1/zz_generated.conversion.go
index b4260c6a3..4795d0e3f 100644
--- a/vendor/volcano.sh/apis/pkg/apis/scheduling/v1beta1/zz_generated.conversion.go
+++ b/vendor/volcano.sh/apis/pkg/apis/scheduling/v1beta1/zz_generated.conversion.go
@@ -171,6 +171,11 @@ func RegisterConversions(s *runtime.Scheme) error {
 	}); err != nil {
 		return err
 	}
+	if err := s.AddGeneratedConversionFunc((*scheduling.QueueSpec)(nil), (*QueueSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
+		return Convert_scheduling_QueueSpec_To_v1beta1_QueueSpec(a.(*scheduling.QueueSpec), b.(*QueueSpec), scope)
+	}); err != nil {
+		return err
+	}
 	if err := s.AddGeneratedConversionFunc((*QueueStatus)(nil), (*scheduling.QueueStatus)(nil), func(a, b interface{}, scope conversion.Scope) error {
 		return Convert_v1beta1_QueueStatus_To_scheduling_QueueStatus(a.(*QueueStatus), b.(*scheduling.QueueStatus), scope)
 	}); err != nil {
@@ -191,11 +196,6 @@ func RegisterConversions(s *runtime.Scheme) error {
 	}); err != nil {
 		return err
 	}
-	if err := s.AddConversionFunc((*scheduling.QueueSpec)(nil), (*QueueSpec)(nil), func(a, b interface{}, scope conversion.Scope) error {
-		return Convert_scheduling_QueueSpec_To_v1beta1_QueueSpec(a.(*scheduling.QueueSpec), b.(*QueueSpec), scope)
-	}); err != nil {
-		return err
-	}
 	return nil
 }
 
@@ -507,17 +507,7 @@ func Convert_scheduling_Queue_To_v1beta1_Queue(in *scheduling.Queue, out *Queue,
 
 func autoConvert_v1beta1_QueueList_To_scheduling_QueueList(in *QueueList, out *scheduling.QueueList, s conversion.Scope) error {
 	out.ListMeta = in.ListMeta
-	if in.Items != nil {
-		in, out := &in.Items, &out.Items
-		*out = make([]scheduling.Queue, len(*in))
-		for i := range *in {
-			if err := Convert_v1beta1_Queue_To_scheduling_Queue(&(*in)[i], &(*out)[i], s); err != nil {
-				return err
-			}
-		}
-	} else {
-		out.Items = nil
-	}
+	out.Items = *(*[]scheduling.Queue)(unsafe.Pointer(&in.Items))
 	return nil
 }
 
@@ -528,17 +518,7 @@ func Convert_v1beta1_QueueList_To_scheduling_QueueList(in *QueueList, out *sched
 
 func autoConvert_scheduling_QueueList_To_v1beta1_QueueList(in *scheduling.QueueList, out *QueueList, s conversion.Scope) error {
 	out.ListMeta = in.ListMeta
-	if in.Items != nil {
-		in, out := &in.Items, &out.Items
-		*out = make([]Queue, len(*in))
-		for i := range *in {
-			if err := Convert_scheduling_Queue_To_v1beta1_Queue(&(*in)[i], &(*out)[i], s); err != nil {
-				return err
-			}
-		}
-	} else {
-		out.Items = nil
-	}
+	out.Items = *(*[]Queue)(unsafe.Pointer(&in.Items))
 	return nil
 }
 
@@ -571,7 +551,6 @@ func Convert_v1beta1_QueueSpec_To_scheduling_QueueSpec(in *QueueSpec, out *sched
 func autoConvert_scheduling_QueueSpec_To_v1beta1_QueueSpec(in *scheduling.QueueSpec, out *QueueSpec, s conversion.Scope) error {
 	out.Weight = in.Weight
 	out.Capability = *(*v1.ResourceList)(unsafe.Pointer(&in.Capability))
-	// WARNING: in.State requires manual conversion: does not exist in peer-type
 	out.Reclaimable = (*bool)(unsafe.Pointer(in.Reclaimable))
 	out.ExtendClusters = *(*[]Cluster)(unsafe.Pointer(&in.ExtendClusters))
 	if err := Convert_scheduling_Guarantee_To_v1beta1_Guarantee(&in.Guarantee, &out.Guarantee, s); err != nil {
@@ -585,6 +564,11 @@ func autoConvert_scheduling_QueueSpec_To_v1beta1_QueueSpec(in *scheduling.QueueS
 	return nil
 }
 
+// Convert_scheduling_QueueSpec_To_v1beta1_QueueSpec is an autogenerated conversion function.
+func Convert_scheduling_QueueSpec_To_v1beta1_QueueSpec(in *scheduling.QueueSpec, out *QueueSpec, s conversion.Scope) error {
+	return autoConvert_scheduling_QueueSpec_To_v1beta1_QueueSpec(in, out, s)
+}
+
 func autoConvert_v1beta1_QueueStatus_To_scheduling_QueueStatus(in *QueueStatus, out *scheduling.QueueStatus, s conversion.Scope) error {
 	out.State = scheduling.QueueState(in.State)
 	out.Unknown = in.Unknown
diff --git a/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/networktopologyspec.go b/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/networktopologyspec.go
index 887393ad3..62f045439 100644
--- a/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/networktopologyspec.go
+++ b/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/networktopologyspec.go
@@ -18,14 +18,14 @@ limitations under the License.
 package v1beta1
 
 import (
-	v1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1"
+	schedulingv1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1"
 )
 
 // NetworkTopologySpecApplyConfiguration represents a declarative configuration of the NetworkTopologySpec type for use
 // with apply.
 type NetworkTopologySpecApplyConfiguration struct {
-	Mode               *v1beta1.NetworkTopologyMode `json:"mode,omitempty"`
-	HighestTierAllowed *int                         `json:"highestTierAllowed,omitempty"`
+	Mode               *schedulingv1beta1.NetworkTopologyMode `json:"mode,omitempty"`
+	HighestTierAllowed *int                                   `json:"highestTierAllowed,omitempty"`
 }
 
 // NetworkTopologySpecApplyConfiguration constructs a declarative configuration of the NetworkTopologySpec type for use with
@@ -37,7 +37,7 @@ func NetworkTopologySpec() *NetworkTopologySpecApplyConfiguration {
 // WithMode sets the Mode field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
 // If called multiple times, the Mode field is set to the value of the last call.
-func (b *NetworkTopologySpecApplyConfiguration) WithMode(value v1beta1.NetworkTopologyMode) *NetworkTopologySpecApplyConfiguration {
+func (b *NetworkTopologySpecApplyConfiguration) WithMode(value schedulingv1beta1.NetworkTopologyMode) *NetworkTopologySpecApplyConfiguration {
 	b.Mode = &value
 	return b
 }
diff --git a/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/podgroup.go b/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/podgroup.go
index 37fef63dc..92bc472f0 100644
--- a/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/podgroup.go
+++ b/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/podgroup.go
@@ -42,6 +42,7 @@ func PodGroup(name, namespace string) *PodGroupApplyConfiguration {
 	b.WithAPIVersion("scheduling.volcano.sh/v1beta1")
 	return b
 }
+func (b PodGroupApplyConfiguration) IsApplyConfiguration() {}
 
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
@@ -217,8 +218,24 @@ func (b *PodGroupApplyConfiguration) WithStatus(value *PodGroupStatusApplyConfig
 	return b
 }
 
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *PodGroupApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *PodGroupApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
 // GetName retrieves the value of the Name field in the declarative configuration.
 func (b *PodGroupApplyConfiguration) GetName() *string {
 	b.ensureObjectMetaApplyConfigurationExists()
 	return b.ObjectMetaApplyConfiguration.Name
 }
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *PodGroupApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
+}
diff --git a/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/queue.go b/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/queue.go
index 5d2b5bc19..8ef487a26 100644
--- a/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/queue.go
+++ b/vendor/volcano.sh/apis/pkg/client/applyconfiguration/scheduling/v1beta1/queue.go
@@ -41,6 +41,7 @@ func Queue(name string) *QueueApplyConfiguration {
 	b.WithAPIVersion("scheduling.volcano.sh/v1beta1")
 	return b
 }
+func (b QueueApplyConfiguration) IsApplyConfiguration() {}
 
 // WithKind sets the Kind field in the declarative configuration to the given value
 // and returns the receiver, so that objects can be built by chaining "With" function invocations.
@@ -216,8 +217,24 @@ func (b *QueueApplyConfiguration) WithStatus(value *QueueStatusApplyConfiguratio
 	return b
 }
 
+// GetKind retrieves the value of the Kind field in the declarative configuration.
+func (b *QueueApplyConfiguration) GetKind() *string {
+	return b.TypeMetaApplyConfiguration.Kind
+}
+
+// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration.
+func (b *QueueApplyConfiguration) GetAPIVersion() *string {
+	return b.TypeMetaApplyConfiguration.APIVersion
+}
+
 // GetName retrieves the value of the Name field in the declarative configuration.
 func (b *QueueApplyConfiguration) GetName() *string {
 	b.ensureObjectMetaApplyConfigurationExists()
 	return b.ObjectMetaApplyConfiguration.Name
 }
+
+// GetNamespace retrieves the value of the Namespace field in the declarative configuration.
+func (b *QueueApplyConfiguration) GetNamespace() *string {
+	b.ensureObjectMetaApplyConfigurationExists()
+	return b.ObjectMetaApplyConfiguration.Namespace
+}



Test patch:
diff --git a/apis/kueue/v1beta1/clusterqueue_conversion_test.go b/apis/kueue/v1beta1/clusterqueue_conversion_test.go
new file mode 100644
index 000000000..e5c15565b
--- /dev/null
+++ b/apis/kueue/v1beta1/clusterqueue_conversion_test.go
@@ -0,0 +1,455 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1beta1
+
+import (
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	"sigs.k8s.io/kueue/apis/kueue/v1beta2"
+)
+
+func TestClusterQueueConvertTo(t *testing.T) {
+	defaultObjectMeta := metav1.ObjectMeta{
+		Name: "test-clusterqueue",
+	}
+
+	testCases := map[string]struct {
+		input    *ClusterQueue
+		expected *v1beta2.ClusterQueue
+	}{
+		"nil cohort": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					Cohort: "",
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					CohortName: "",
+				},
+			},
+		},
+		"cohort to cohortName conversion": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					Cohort: "test-cohort",
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					CohortName: "test-cohort",
+				},
+			},
+		},
+		"AdmissionChecks to AdmissionChecksStrategy conversion": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					AdmissionChecks: []AdmissionCheckReference{"check1", "check2"},
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					AdmissionChecksStrategy: &v1beta2.AdmissionChecksStrategy{
+						AdmissionChecks: []v1beta2.AdmissionCheckStrategyRule{
+							{Name: "check1"},
+							{Name: "check2"},
+						},
+					},
+				},
+			},
+		},
+		"AdmissionChecksStrategy preserved": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					AdmissionChecksStrategy: &AdmissionChecksStrategy{
+						AdmissionChecks: []AdmissionCheckStrategyRule{
+							{Name: "strategy-check1"},
+							{Name: "strategy-check2"},
+						},
+					},
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					AdmissionChecksStrategy: &v1beta2.AdmissionChecksStrategy{
+						AdmissionChecks: []v1beta2.AdmissionCheckStrategyRule{
+							{Name: "strategy-check1"},
+							{Name: "strategy-check2"},
+						},
+					},
+				},
+			},
+		},
+		"empty AdmissionChecks": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					AdmissionChecks: []AdmissionCheckReference{},
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec:       v1beta2.ClusterQueueSpec{},
+			},
+		},
+		"FlavorFungibility Preempt to MayStopSearch": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanPreempt: Preempt,
+					},
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					FlavorFungibility: &v1beta2.FlavorFungibility{
+						WhenCanPreempt: v1beta2.MayStopSearch,
+					},
+				},
+			},
+		},
+		"FlavorFungibility Borrow to MayStopSearch": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanBorrow: Borrow,
+					},
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					FlavorFungibility: &v1beta2.FlavorFungibility{
+						WhenCanBorrow: v1beta2.MayStopSearch,
+					},
+				},
+			},
+		},
+		"FlavorFungibility MayStopSearch preserved": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanPreempt: MayStopSearch,
+						WhenCanBorrow:  MayStopSearch,
+					},
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					FlavorFungibility: &v1beta2.FlavorFungibility{
+						WhenCanPreempt: v1beta2.MayStopSearch,
+						WhenCanBorrow:  v1beta2.MayStopSearch,
+					},
+				},
+			},
+		},
+		"FlavorFungibility TryNextFlavor preserved": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanPreempt: TryNextFlavor,
+						WhenCanBorrow:  TryNextFlavor,
+					},
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					FlavorFungibility: &v1beta2.FlavorFungibility{
+						WhenCanPreempt: v1beta2.TryNextFlavor,
+						WhenCanBorrow:  v1beta2.TryNextFlavor,
+					},
+				},
+			},
+		},
+		"complete ClusterQueue with all fields": {
+			input: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					Cohort:          "prod-cohort",
+					AdmissionChecks: []AdmissionCheckReference{"multikueue-check"},
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanPreempt: TryNextFlavor,
+						WhenCanBorrow:  MayStopSearch,
+					},
+					QueueingStrategy: StrictFIFO,
+				},
+				Status: ClusterQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					PendingWorkloads: 5,
+				},
+			},
+			expected: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					CohortName: "prod-cohort",
+					AdmissionChecksStrategy: &v1beta2.AdmissionChecksStrategy{
+						AdmissionChecks: []v1beta2.AdmissionCheckStrategyRule{
+							{Name: "multikueue-check"},
+						},
+					},
+					FlavorFungibility: &v1beta2.FlavorFungibility{
+						WhenCanPreempt: v1beta2.TryNextFlavor,
+						WhenCanBorrow:  v1beta2.MayStopSearch,
+					},
+					QueueingStrategy: v1beta2.StrictFIFO,
+				},
+				Status: v1beta2.ClusterQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					PendingWorkloads: 5,
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			result := &v1beta2.ClusterQueue{}
+			if err := tc.input.ConvertTo(result); err != nil {
+				t.Fatalf("ConvertTo failed: %v", err)
+			}
+			if diff := cmp.Diff(tc.expected, result); diff != "" {
+				t.Errorf("unexpected conversion result (-want +got):\n%s", diff)
+			}
+		})
+	}
+}
+
+func TestClusterQueueConvertFrom(t *testing.T) {
+	defaultObjectMeta := metav1.ObjectMeta{
+		Name: "test-clusterqueue",
+	}
+
+	testCases := map[string]struct {
+		input    *v1beta2.ClusterQueue
+		expected *ClusterQueue
+	}{
+		"nil cohortName": {
+			input: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					CohortName: "",
+				},
+			},
+			expected: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					Cohort: "",
+				},
+			},
+		},
+		"cohortName to cohort conversion": {
+			input: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					CohortName: "test-cohort",
+				},
+			},
+			expected: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					Cohort: "test-cohort",
+				},
+			},
+		},
+		"FlavorFungibility MayStopSearch preserved": {
+			input: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					FlavorFungibility: &v1beta2.FlavorFungibility{
+						WhenCanPreempt: v1beta2.MayStopSearch,
+						WhenCanBorrow:  v1beta2.MayStopSearch,
+					},
+				},
+			},
+			expected: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanPreempt: MayStopSearch,
+						WhenCanBorrow:  MayStopSearch,
+					},
+				},
+			},
+		},
+		"FlavorFungibility TryNextFlavor preserved": {
+			input: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					FlavorFungibility: &v1beta2.FlavorFungibility{
+						WhenCanPreempt: v1beta2.TryNextFlavor,
+						WhenCanBorrow:  v1beta2.TryNextFlavor,
+					},
+				},
+			},
+			expected: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanPreempt: TryNextFlavor,
+						WhenCanBorrow:  TryNextFlavor,
+					},
+				},
+			},
+		},
+		"complete ClusterQueue with all fields": {
+			input: &v1beta2.ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.ClusterQueueSpec{
+					CohortName: "prod-cohort",
+					FlavorFungibility: &v1beta2.FlavorFungibility{
+						WhenCanPreempt: v1beta2.MayStopSearch,
+						WhenCanBorrow:  v1beta2.TryNextFlavor,
+					},
+					QueueingStrategy: v1beta2.StrictFIFO,
+				},
+				Status: v1beta2.ClusterQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					PendingWorkloads: 5,
+				},
+			},
+			expected: &ClusterQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: ClusterQueueSpec{
+					Cohort: "prod-cohort",
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanPreempt: MayStopSearch,
+						WhenCanBorrow:  TryNextFlavor,
+					},
+					QueueingStrategy: StrictFIFO,
+				},
+				Status: ClusterQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					PendingWorkloads: 5,
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			result := &ClusterQueue{}
+			if err := result.ConvertFrom(tc.input); err != nil {
+				t.Fatalf("ConvertFrom failed: %v", err)
+			}
+			if diff := cmp.Diff(tc.expected, result); diff != "" {
+				t.Errorf("unexpected conversion result (-want +got):\n%s", diff)
+			}
+		})
+	}
+}
+
+func TestClusterQueueConversion_RoundTrip(t *testing.T) {
+	testCases := map[string]struct {
+		v1beta1Obj *ClusterQueue
+	}{
+		"complete ClusterQueue with cohort and FlavorFungibility": {
+			v1beta1Obj: &ClusterQueue{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "test-clusterqueue",
+				},
+				Spec: ClusterQueueSpec{
+					Cohort: "prod-cohort",
+					FlavorFungibility: &FlavorFungibility{
+						WhenCanPreempt: TryNextFlavor,
+						WhenCanBorrow:  MayStopSearch,
+					},
+					QueueingStrategy: StrictFIFO,
+				},
+				Status: ClusterQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					PendingWorkloads: 10,
+				},
+			},
+		},
+		"minimal ClusterQueue": {
+			v1beta1Obj: &ClusterQueue{
+				ObjectMeta: metav1.ObjectMeta{
+					Name: "minimal-cq",
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			// Convert v1beta1 -> v1beta2
+			v1beta2Obj := &v1beta2.ClusterQueue{}
+			if err := tc.v1beta1Obj.ConvertTo(v1beta2Obj); err != nil {
+				t.Fatalf("ConvertTo failed: %v", err)
+			}
+
+			// Convert v1beta2 -> v1beta1 (round-trip)
+			roundTripped := &ClusterQueue{}
+			if err := roundTripped.ConvertFrom(v1beta2Obj); err != nil {
+				t.Fatalf("ConvertFrom failed: %v", err)
+			}
+
+			// Verify round-trip
+			if diff := cmp.Diff(tc.v1beta1Obj, roundTripped); diff != "" {
+				t.Errorf("round-trip conversion produced diff (-original +roundtripped):\n%s", diff)
+			}
+		})
+	}
+}
diff --git a/apis/kueue/v1beta1/localqueue_conversion_test.go b/apis/kueue/v1beta1/localqueue_conversion_test.go
new file mode 100644
index 000000000..f7c5821ef
--- /dev/null
+++ b/apis/kueue/v1beta1/localqueue_conversion_test.go
@@ -0,0 +1,530 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1beta1
+
+import (
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/api/resource"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	"sigs.k8s.io/kueue/apis/kueue/v1beta2"
+)
+
+func TestLocalQueueConvertTo(t *testing.T) {
+	defaultObjectMeta := metav1.ObjectMeta{
+		Name:      "test-localqueue",
+		Namespace: "default",
+	}
+
+	testCases := map[string]struct {
+		input    *LocalQueue
+		expected *v1beta2.LocalQueue
+	}{
+		"nil FlavorUsage": {
+			input: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: LocalQueueStatus{
+					FlavorUsage: nil,
+				},
+			},
+			expected: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.LocalQueueStatus{
+					FlavorsUsage: nil,
+				},
+			},
+		},
+		"empty FlavorUsage": {
+			input: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: LocalQueueStatus{
+					FlavorUsage: []LocalQueueFlavorUsage{},
+				},
+			},
+			expected: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.LocalQueueStatus{
+					FlavorsUsage: []v1beta2.LocalQueueFlavorUsage{},
+				},
+			},
+		},
+		"single FlavorUsage": {
+			input: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: LocalQueueStatus{
+					FlavorUsage: []LocalQueueFlavorUsage{
+						{
+							Name: "default-flavor",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+				},
+			},
+			expected: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.LocalQueueStatus{
+					FlavorsUsage: []v1beta2.LocalQueueFlavorUsage{
+						{
+							Name: "default-flavor",
+							Resources: []v1beta2.LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+		"multiple FlavorUsage with various resources": {
+			input: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: LocalQueueStatus{
+					FlavorUsage: []LocalQueueFlavorUsage{
+						{
+							Name: "flavor-1",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+								{
+									Name:  corev1.ResourceMemory,
+									Total: resource.MustParse("20Gi"),
+								},
+							},
+						},
+						{
+							Name: "flavor-2",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("5"),
+								},
+							},
+						},
+					},
+					PendingWorkloads:   3,
+					ReservingWorkloads: 2,
+					AdmittedWorkloads:  1,
+				},
+			},
+			expected: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.LocalQueueStatus{
+					FlavorsUsage: []v1beta2.LocalQueueFlavorUsage{
+						{
+							Name: "flavor-1",
+							Resources: []v1beta2.LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+								{
+									Name:  corev1.ResourceMemory,
+									Total: resource.MustParse("20Gi"),
+								},
+							},
+						},
+						{
+							Name: "flavor-2",
+							Resources: []v1beta2.LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("5"),
+								},
+							},
+						},
+					},
+					PendingWorkloads:   3,
+					ReservingWorkloads: 2,
+					AdmittedWorkloads:  1,
+				},
+			},
+		},
+		"with conditions and status fields": {
+			input: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: LocalQueueSpec{
+					ClusterQueue: "cluster-queue-1",
+				},
+				Status: LocalQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					FlavorUsage: []LocalQueueFlavorUsage{
+						{
+							Name: "default-flavor",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+					PendingWorkloads: 5,
+				},
+			},
+			expected: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.LocalQueueSpec{
+					ClusterQueue: "cluster-queue-1",
+				},
+				Status: v1beta2.LocalQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					FlavorsUsage: []v1beta2.LocalQueueFlavorUsage{
+						{
+							Name: "default-flavor",
+							Resources: []v1beta2.LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+					PendingWorkloads: 5,
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			result := &v1beta2.LocalQueue{}
+			if err := tc.input.ConvertTo(result); err != nil {
+				t.Fatalf("ConvertTo failed: %v", err)
+			}
+			if diff := cmp.Diff(tc.expected, result); diff != "" {
+				t.Errorf("unexpected conversion result (-want +got):\n%s", diff)
+			}
+		})
+	}
+}
+
+func TestLocalQueueConvertFrom(t *testing.T) {
+	defaultObjectMeta := metav1.ObjectMeta{
+		Name:      "test-localqueue",
+		Namespace: "default",
+	}
+
+	testCases := map[string]struct {
+		input    *v1beta2.LocalQueue
+		expected *LocalQueue
+	}{
+		"nil FlavorsUsage": {
+			input: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.LocalQueueStatus{
+					FlavorsUsage: nil,
+				},
+			},
+			expected: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: LocalQueueStatus{
+					FlavorUsage: nil,
+				},
+			},
+		},
+		"empty FlavorsUsage": {
+			input: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.LocalQueueStatus{
+					FlavorsUsage: []v1beta2.LocalQueueFlavorUsage{},
+				},
+			},
+			expected: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: LocalQueueStatus{
+					FlavorUsage: []LocalQueueFlavorUsage{},
+				},
+			},
+		},
+		"single FlavorsUsage": {
+			input: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.LocalQueueStatus{
+					FlavorsUsage: []v1beta2.LocalQueueFlavorUsage{
+						{
+							Name: "default-flavor",
+							Resources: []v1beta2.LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+				},
+			},
+			expected: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: LocalQueueStatus{
+					FlavorUsage: []LocalQueueFlavorUsage{
+						{
+							Name: "default-flavor",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+		"multiple FlavorsUsage with various resources": {
+			input: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.LocalQueueStatus{
+					FlavorsUsage: []v1beta2.LocalQueueFlavorUsage{
+						{
+							Name: "flavor-1",
+							Resources: []v1beta2.LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+								{
+									Name:  corev1.ResourceMemory,
+									Total: resource.MustParse("20Gi"),
+								},
+							},
+						},
+						{
+							Name: "flavor-2",
+							Resources: []v1beta2.LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("5"),
+								},
+							},
+						},
+					},
+					PendingWorkloads:   3,
+					ReservingWorkloads: 2,
+					AdmittedWorkloads:  1,
+				},
+			},
+			expected: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Status: LocalQueueStatus{
+					FlavorUsage: []LocalQueueFlavorUsage{
+						{
+							Name: "flavor-1",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+								{
+									Name:  corev1.ResourceMemory,
+									Total: resource.MustParse("20Gi"),
+								},
+							},
+						},
+						{
+							Name: "flavor-2",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("5"),
+								},
+							},
+						},
+					},
+					PendingWorkloads:   3,
+					ReservingWorkloads: 2,
+					AdmittedWorkloads:  1,
+				},
+			},
+		},
+		"with conditions and status fields": {
+			input: &v1beta2.LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.LocalQueueSpec{
+					ClusterQueue: "cluster-queue-1",
+				},
+				Status: v1beta2.LocalQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					FlavorsUsage: []v1beta2.LocalQueueFlavorUsage{
+						{
+							Name: "default-flavor",
+							Resources: []v1beta2.LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+					PendingWorkloads: 5,
+				},
+			},
+			expected: &LocalQueue{
+				ObjectMeta: defaultObjectMeta,
+				Spec: LocalQueueSpec{
+					ClusterQueue: "cluster-queue-1",
+				},
+				Status: LocalQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					FlavorUsage: []LocalQueueFlavorUsage{
+						{
+							Name: "default-flavor",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+					PendingWorkloads: 5,
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			result := &LocalQueue{}
+			if err := result.ConvertFrom(tc.input); err != nil {
+				t.Fatalf("ConvertFrom failed: %v", err)
+			}
+			if diff := cmp.Diff(tc.expected, result); diff != "" {
+				t.Errorf("unexpected conversion result (-want +got):\n%s", diff)
+			}
+		})
+	}
+}
+
+func TestLocalQueueConversion_RoundTrip(t *testing.T) {
+	testCases := map[string]struct {
+		v1beta1Obj *LocalQueue
+	}{
+		"complete LocalQueue with multiple flavors": {
+			v1beta1Obj: &LocalQueue{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "test-localqueue",
+					Namespace: "default",
+				},
+				Spec: LocalQueueSpec{
+					ClusterQueue: "main-cluster-queue",
+				},
+				Status: LocalQueueStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Active",
+							Status: metav1.ConditionTrue,
+							Reason: "Ready",
+						},
+					},
+					FlavorUsage: []LocalQueueFlavorUsage{
+						{
+							Name: "flavor-1",
+							Resources: []LocalQueueResourceUsage{
+								{
+									Name:  corev1.ResourceCPU,
+									Total: resource.MustParse("10"),
+								},
+							},
+						},
+					},
+					PendingWorkloads:   5,
+					ReservingWorkloads: 3,
+					AdmittedWorkloads:  2,
+				},
+			},
+		},
+		"LocalQueue with nil FlavorUsage": {
+			v1beta1Obj: &LocalQueue{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "simple-localqueue",
+					Namespace: "test-ns",
+				},
+				Status: LocalQueueStatus{
+					FlavorUsage: nil,
+				},
+			},
+		},
+		"LocalQueue with empty FlavorUsage": {
+			v1beta1Obj: &LocalQueue{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      "empty-flavor-localqueue",
+					Namespace: "test-ns",
+				},
+				Status: LocalQueueStatus{
+					FlavorUsage: []LocalQueueFlavorUsage{},
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			// Convert v1beta1 -> v1beta2
+			v1beta2Obj := &v1beta2.LocalQueue{}
+			if err := tc.v1beta1Obj.ConvertTo(v1beta2Obj); err != nil {
+				t.Fatalf("ConvertTo failed: %v", err)
+			}
+
+			// Convert v1beta2 -> v1beta1 (round-trip)
+			roundTripped := &LocalQueue{}
+			if err := roundTripped.ConvertFrom(v1beta2Obj); err != nil {
+				t.Fatalf("ConvertFrom failed: %v", err)
+			}
+
+			// Verify round-trip
+			if diff := cmp.Diff(tc.v1beta1Obj, roundTripped); diff != "" {
+				t.Errorf("round-trip conversion produced diff (-original +roundtripped):\n%s", diff)
+			}
+		})
+	}
+}
diff --git a/apis/kueue/v1beta1/workload_conversion_test.go b/apis/kueue/v1beta1/workload_conversion_test.go
new file mode 100644
index 000000000..e9b9bdd0a
--- /dev/null
+++ b/apis/kueue/v1beta1/workload_conversion_test.go
@@ -0,0 +1,385 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1beta1
+
+import (
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/utils/ptr"
+
+	"sigs.k8s.io/kueue/apis/kueue/v1beta2"
+)
+
+func TestWorkloadConvertTo(t *testing.T) {
+	defaultObjectMeta := metav1.ObjectMeta{
+		Name:      "test-workload",
+		Namespace: "default",
+	}
+
+	testCases := map[string]struct {
+		input    *Workload
+		expected *v1beta2.Workload
+	}{
+		"nil AccumulatedPastExexcutionTimeSeconds": {
+			input: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					AccumulatedPastExexcutionTimeSeconds: nil,
+				},
+			},
+			expected: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.WorkloadStatus{
+					AccumulatedPastExecutionTimeSeconds: nil,
+				},
+			},
+		},
+		"zero AccumulatedPastExexcutionTimeSeconds": {
+			input: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](0),
+				},
+			},
+			expected: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.WorkloadStatus{
+					AccumulatedPastExecutionTimeSeconds: ptr.To[int32](0),
+				},
+			},
+		},
+		"non-zero AccumulatedPastExexcutionTimeSeconds": {
+			input: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](3600),
+				},
+			},
+			expected: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.WorkloadStatus{
+					AccumulatedPastExecutionTimeSeconds: ptr.To[int32](3600),
+				},
+			},
+		},
+		"with conditions and other fields": {
+			input: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Admitted",
+							Status: metav1.ConditionTrue,
+							Reason: "AdmittedByClusterQueue",
+						},
+					},
+					AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](7200),
+				},
+			},
+			expected: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.WorkloadStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Admitted",
+							Status: metav1.ConditionTrue,
+							Reason: "AdmittedByClusterQueue",
+						},
+					},
+					AccumulatedPastExecutionTimeSeconds: ptr.To[int32](7200),
+				},
+			},
+		},
+		"with PodPriorityClassSource": {
+			input: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: WorkloadSpec{
+					Priority:            ptr.To[int32](100),
+					PriorityClassSource: PodPriorityClassSource,
+					PriorityClassName:   "low",
+				},
+			},
+			expected: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.WorkloadSpec{
+					Priority: ptr.To[int32](100),
+					PriorityClassRef: &v1beta2.PriorityClassRef{
+						Group: v1beta2.PodPriorityClassGroup,
+						Kind:  v1beta2.PodPriorityClassKind,
+						Name:  "low",
+					},
+				},
+			},
+		},
+		"with WorkloadPriorityClassSource": {
+			input: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: WorkloadSpec{
+					Priority:            ptr.To[int32](100),
+					PriorityClassSource: WorkloadPriorityClassSource,
+					PriorityClassName:   "low",
+				},
+			},
+			expected: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.WorkloadSpec{
+					Priority: ptr.To[int32](100),
+					PriorityClassRef: &v1beta2.PriorityClassRef{
+						Group: v1beta2.WorkloadPriorityClassGroup,
+						Kind:  v1beta2.WorkloadPriorityClassKind,
+						Name:  "low",
+					},
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			result := &v1beta2.Workload{}
+			if err := tc.input.ConvertTo(result); err != nil {
+				t.Fatalf("ConvertTo failed: %v", err)
+			}
+			if diff := cmp.Diff(tc.expected, result); diff != "" {
+				t.Errorf("unexpected conversion result (-want +got):\n%s", diff)
+			}
+		})
+	}
+}
+
+func TestWorkloadConvertFrom(t *testing.T) {
+	defaultObjectMeta := metav1.ObjectMeta{
+		Name:      "test-workload",
+		Namespace: "default",
+	}
+
+	testCases := map[string]struct {
+		input    *v1beta2.Workload
+		expected *Workload
+	}{
+		"nil AccumulatedPastExecutionTimeSeconds": {
+			input: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.WorkloadStatus{
+					AccumulatedPastExecutionTimeSeconds: nil,
+				},
+			},
+			expected: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					AccumulatedPastExexcutionTimeSeconds: nil,
+				},
+			},
+		},
+		"zero AccumulatedPastExecutionTimeSeconds": {
+			input: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.WorkloadStatus{
+					AccumulatedPastExecutionTimeSeconds: ptr.To[int32](0),
+				},
+			},
+			expected: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](0),
+				},
+			},
+		},
+		"non-zero AccumulatedPastExecutionTimeSeconds": {
+			input: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.WorkloadStatus{
+					AccumulatedPastExecutionTimeSeconds: ptr.To[int32](3600),
+				},
+			},
+			expected: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](3600),
+				},
+			},
+		},
+		"with conditions and other fields": {
+			input: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: v1beta2.WorkloadStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Finished",
+							Status: metav1.ConditionTrue,
+							Reason: "JobFinished",
+						},
+					},
+					AccumulatedPastExecutionTimeSeconds: ptr.To[int32](1800),
+				},
+			},
+			expected: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Finished",
+							Status: metav1.ConditionTrue,
+							Reason: "JobFinished",
+						},
+					},
+					AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](1800),
+				},
+			},
+		},
+		"with PodPriorityClassRef": {
+			input: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.WorkloadSpec{
+					Priority: ptr.To[int32](100),
+					PriorityClassRef: &v1beta2.PriorityClassRef{
+						Group: v1beta2.PodPriorityClassGroup,
+						Kind:  v1beta2.PodPriorityClassKind,
+						Name:  "low",
+					},
+				},
+			},
+			expected: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: WorkloadSpec{
+					Priority:            ptr.To[int32](100),
+					PriorityClassSource: PodPriorityClassSource,
+					PriorityClassName:   "low",
+				},
+			},
+		},
+		"with WorkloadPriorityClassRef": {
+			input: &v1beta2.Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: v1beta2.WorkloadSpec{
+					Priority: ptr.To[int32](100),
+					PriorityClassRef: &v1beta2.PriorityClassRef{
+						Group: v1beta2.WorkloadPriorityClassGroup,
+						Kind:  v1beta2.WorkloadPriorityClassKind,
+						Name:  "low",
+					},
+				},
+			},
+			expected: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: WorkloadSpec{
+					Priority:            ptr.To[int32](100),
+					PriorityClassSource: WorkloadPriorityClassSource,
+					PriorityClassName:   "low",
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			result := &Workload{}
+			if err := result.ConvertFrom(tc.input); err != nil {
+				t.Fatalf("ConvertFrom failed: %v", err)
+			}
+			if diff := cmp.Diff(tc.expected, result); diff != "" {
+				t.Errorf("unexpected conversion result (-want +got):\n%s", diff)
+			}
+		})
+	}
+}
+
+func TestWorkloadConversion_RoundTrip(t *testing.T) {
+	defaultObjectMeta := metav1.ObjectMeta{
+		Name:      "test-workload",
+		Namespace: "default",
+	}
+
+	testCases := map[string]struct {
+		v1beta1Obj *Workload
+	}{
+		"complete Workload with AccumulatedPastExexcutionTimeSeconds": {
+			v1beta1Obj: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					Conditions: []metav1.Condition{
+						{
+							Type:   "Admitted",
+							Status: metav1.ConditionTrue,
+							Reason: "AdmittedByClusterQueue",
+						},
+					},
+					AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](5400),
+				},
+			},
+		},
+		"Workload with nil AccumulatedPastExexcutionTimeSeconds": {
+			v1beta1Obj: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					AccumulatedPastExexcutionTimeSeconds: nil,
+				},
+			},
+		},
+		"Workload with zero AccumulatedPastExexcutionTimeSeconds": {
+			v1beta1Obj: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Status: WorkloadStatus{
+					AccumulatedPastExexcutionTimeSeconds: ptr.To[int32](0),
+				},
+			},
+		},
+		"Workload with PodPriorityClassSource": {
+			v1beta1Obj: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: WorkloadSpec{
+					Priority:            ptr.To[int32](100),
+					PriorityClassSource: PodPriorityClassSource,
+					PriorityClassName:   "low",
+				},
+			},
+		},
+		"Workload with WorkloadPriorityClassSource": {
+			v1beta1Obj: &Workload{
+				ObjectMeta: defaultObjectMeta,
+				Spec: WorkloadSpec{
+					Priority:            ptr.To[int32](100),
+					PriorityClassSource: WorkloadPriorityClassSource,
+					PriorityClassName:   "low",
+				},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			// Convert v1beta1 -> v1beta2
+			v1beta2Obj := &v1beta2.Workload{}
+			if err := tc.v1beta1Obj.ConvertTo(v1beta2Obj); err != nil {
+				t.Fatalf("ConvertTo failed: %v", err)
+			}
+
+			// Convert v1beta2 -> v1beta1 (round-trip)
+			roundTripped := &Workload{}
+			if err := roundTripped.ConvertFrom(v1beta2Obj); err != nil {
+				t.Fatalf("ConvertFrom failed: %v", err)
+			}
+
+			// Verify round-trip
+			if diff := cmp.Diff(tc.v1beta1Obj, roundTripped); diff != "" {
+				t.Errorf("round-trip conversion produced diff (-original +roundtripped):\n%s", diff)
+			}
+		})
+	}
+}
diff --git a/pkg/cache/queue/cluster_queue_test.go b/pkg/cache/queue/cluster_queue_test.go
index 5544fc3a9..51839ec45 100644
--- a/pkg/cache/queue/cluster_queue_test.go
+++ b/pkg/cache/queue/cluster_queue_test.go
@@ -160,11 +160,11 @@ func Test_PushOrUpdate(t *testing.T) {
 			ctx, _ := utiltesting.ContextWithLog(t)
 			cq := newClusterQueueImpl(ctx, nil, defaultOrdering, fakeClock, nil, false, nil)
 
-			if cq.Pending() != 0 {
+			if cq.PendingTotal() != 0 {
 				t.Error("ClusterQueue should be empty")
 			}
 			cq.PushOrUpdate(workload.NewInfo(tc.workload.Clone().Obj()))
-			if cq.Pending() != 1 {
+			if cq.PendingTotal() != 1 {
 				t.Error("ClusterQueue should have one workload")
 			}
 
@@ -172,8 +172,8 @@ func Test_PushOrUpdate(t *testing.T) {
 			updatedWl := tc.workload.Clone().ResourceVersion("1").Obj()
 			cq.PushOrUpdate(workload.NewInfo(updatedWl))
 			newWl := cq.Pop()
-			if newWl != nil && cq.Pending() != 1 {
-				t.Errorf("unexpected count of pending workloads (want=%d, got=%d)", 1, cq.Pending())
+			if newWl != nil && cq.PendingTotal() != 1 {
+				t.Errorf("unexpected count of pending workloads (want=%d, got=%d)", 1, cq.PendingTotal())
 			}
 			if diff := cmp.Diff(tc.wantWorkload, newWl, cmpOpts...); len(diff) != 0 {
 				t.Errorf("Unexpected workloads in heap (-want,+got):\n%s", diff)
@@ -216,17 +216,17 @@ func Test_Delete(t *testing.T) {
 	wl2 := utiltestingapi.MakeWorkload("workload-2", defaultNamespace).Obj()
 	cq.PushOrUpdate(workload.NewInfo(wl1))
 	cq.PushOrUpdate(workload.NewInfo(wl2))
-	if cq.Pending() != 2 {
+	if cq.PendingTotal() != 2 {
 		t.Error("ClusterQueue should have two workload")
 	}
 	cq.Delete(wl1)
-	if cq.Pending() != 1 {
+	if cq.PendingTotal() != 1 {
 		t.Error("ClusterQueue should have only one workload")
 	}
 	// Change workload item, ClusterQueue.Delete should only care about the namespace and name.
 	wl2.Spec = kueue.WorkloadSpec{QueueName: "default"}
 	cq.Delete(wl2)
-	if cq.Pending() != 0 {
+	if cq.PendingTotal() != 0 {
 		t.Error("ClusterQueue should have be empty")
 	}
 }
@@ -288,15 +288,15 @@ func Test_DeleteFromLocalQueue(t *testing.T) {
 	}
 
 	wantPending := len(admissibleworkloads) + len(inadmissibleWorkloads)
-	if pending := cq.Pending(); pending != wantPending {
-		t.Errorf("clusterQueue's workload number not right, want %v, got %v", wantPending, pending)
+	if cq.PendingTotal() != wantPending {
+		t.Errorf("clusterQueue's workload number not right, want %v, got %v", wantPending, cq.PendingTotal())
 	}
 	if len(cq.inadmissibleWorkloads) != len(inadmissibleWorkloads) {
 		t.Errorf("clusterQueue's workload number in inadmissibleWorkloads not right, want %v, got %v", len(inadmissibleWorkloads), len(cq.inadmissibleWorkloads))
 	}
 
 	cq.DeleteFromLocalQueue(qImpl)
-	if cq.Pending() != 0 {
+	if cq.PendingTotal() != 0 {
 		t.Error("clusterQueue should be empty")
 	}
 }
@@ -466,8 +466,8 @@ func TestClusterQueueImpl(t *testing.T) {
 			if diff := cmp.Diff(test.wantActiveWorkloads, gotWorkloads, cmpDump...); diff != "" {
 				t.Errorf("Unexpected active workloads in cluster foo (-want,+got):\n%s", diff)
 			}
-			if got := cq.Pending(); got != test.wantPending {
-				t.Errorf("Got %d pending workloads, want %d", got, test.wantPending)
+			if cq.PendingTotal() != test.wantPending {
+				t.Errorf("Got %d pending workloads, want %d", cq.PendingTotal(), test.wantPending)
 			}
 		})
 	}
@@ -728,12 +728,12 @@ func TestStrictFIFO(t *testing.T) {
 			name: "w1.priority is higher than w2.priority",
 			w1: utiltestingapi.MakeWorkload("w1", "").
 				Creation(t1).
-				PriorityClass("highPriority").
+				PodPriorityClassRef("highPriority").
 				Priority(highPriority).
 				Obj(),
 			w2: utiltestingapi.MakeWorkload("w2", "").
 				Creation(t2).
-				PriorityClass("lowPriority").
+				PodPriorityClassRef("lowPriority").
 				Priority(lowPriority).
 				Obj(),
 			expected: "w1",
@@ -789,12 +789,12 @@ func TestStrictFIFO(t *testing.T) {
 			name: "p1.priority is lower than p2.priority and w1.create time is earlier than w2.create time",
 			w1: utiltestingapi.MakeWorkload("w1", "").
 				Creation(t1).
-				PriorityClass("lowPriority").
+				PodPriorityClassRef("lowPriority").
 				Priority(lowPriority).
 				Obj(),
 			w2: utiltestingapi.MakeWorkload("w2", "").
 				Creation(t2).
-				PriorityClass("highPriority").
+				PodPriorityClassRef("highPriority").
 				Priority(highPriority).
 				Obj(),
 			expected: "w2",
diff --git a/pkg/cache/scheduler/clusterqueue_test.go b/pkg/cache/scheduler/clusterqueue_test.go
index 31cdf2c89..6289f5a85 100644
--- a/pkg/cache/scheduler/clusterqueue_test.go
+++ b/pkg/cache/scheduler/clusterqueue_test.go
@@ -548,7 +548,7 @@ func TestClusterQueueReadinessWithTAS(t *testing.T) {
 			wantMessage: "Can admit new workloads",
 		},
 		{
-			name: "TAS do not support MultiKueue AdmissionCheck",
+			name: "TAS supports MultiKueue AdmissionCheck",
 			cq: utiltestingapi.MakeClusterQueue("cq").
 				ResourceGroup(
 					*utiltestingapi.MakeFlavorQuotas("tas-flavor").
@@ -561,8 +561,8 @@ func TestClusterQueueReadinessWithTAS(t *testing.T) {
 						ResourceQuotaWrapper("example.com/gpu").NominalQuota("5").Append().
 						Obj(),
 				).AdmissionChecks("mk-check").Obj(),
-			wantReason:  kueue.ClusterQueueActiveReasonNotSupportedWithTopologyAwareScheduling,
-			wantMessage: "Can't admit new workloads: TAS is not supported with MultiKueue admission check.",
+			wantReason:  kueue.ClusterQueueActiveReasonReady,
+			wantMessage: "Can admit new workloads",
 		},
 		{
 			name:         "Referenced TAS flavor without topology",
diff --git a/pkg/cache/scheduler/tas_balanced_placement_test.go b/pkg/cache/scheduler/tas_balanced_placement_test.go
new file mode 100644
index 000000000..7892bbe7e
--- /dev/null
+++ b/pkg/cache/scheduler/tas_balanced_placement_test.go
@@ -0,0 +1,169 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package scheduler
+
+import (
+	"sort"
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	"github.com/google/go-cmp/cmp/cmpopts"
+
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
+)
+
+func TestSelectOptimalDomainSetToFit(t *testing.T) {
+	d1 := &domain{id: "d1", state: 9, sliceState: 9, leaderState: 1, stateWithLeader: 8, sliceStateWithLeader: 8}
+	d2 := &domain{id: "d2", state: 6, sliceState: 6, leaderState: 0, stateWithLeader: 6, sliceStateWithLeader: 6}
+	d3 := &domain{id: "d3", state: 4, sliceState: 4, leaderState: 1, stateWithLeader: 3, sliceStateWithLeader: 3}
+	d4 := &domain{id: "d4", state: 2, sliceState: 2, leaderState: 0, stateWithLeader: 2, sliceStateWithLeader: 2}
+
+	testCases := map[string]struct {
+		domains     []*domain
+		workerCount int32
+		leaderCount int32
+		want        []string
+	}{
+		"no fit": {
+			domains:     []*domain{d1, d2, d3, d4},
+			workerCount: 22,
+			leaderCount: 0,
+			want:        []string{},
+		},
+		"simple fit one domain": {
+			domains:     []*domain{d1, d2, d3, d4},
+			workerCount: 5,
+			leaderCount: 1,
+			want:        []string{"d1"},
+		},
+		"perfect fit with two domains": {
+			domains:     []*domain{d1, d2, d3, d4},
+			workerCount: 9,
+			leaderCount: 1,
+			want:        []string{"d2", "d3"},
+		},
+		"perfect fit with two domains 2": {
+			domains:     []*domain{d1, d2, d3, d4},
+			workerCount: 10,
+			leaderCount: 1,
+			want:        []string{"d1", "d4"},
+		},
+		"best fit, single domain": {
+			domains:     []*domain{d1, d2, d3, d4},
+			workerCount: 5,
+			leaderCount: 0,
+			want:        []string{"d2"},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			_, log := utiltesting.ContextWithLog(t)
+			s := newTASFlavorSnapshot(log, "dummy", []string{}, nil)
+			got := selectOptimalDomainSetToFit(s, tc.domains, tc.workerCount, tc.leaderCount, 1, true)
+			gotIDs := make([]string, len(got))
+			for i, d := range got {
+				gotIDs[i] = string(d.id)
+			}
+			sort.Strings(gotIDs)
+			sort.Strings(tc.want)
+			if diff := cmp.Diff(tc.want, gotIDs); diff != "" {
+				t.Errorf("unexpected optimal domain set (-want,+got): %s", diff)
+			}
+		})
+	}
+}
+
+func TestPlaceSlicesOnDomainsBalanced(t *testing.T) {
+	d1 := &domain{id: "d1", state: 18, sliceState: 18, stateWithLeader: 18, leaderState: 0, sliceStateWithLeader: 18}
+	d2 := &domain{id: "d2", state: 18, sliceState: 18, stateWithLeader: 18, leaderState: 0, sliceStateWithLeader: 18}
+	d3 := &domain{id: "d3", state: 18, sliceState: 18, stateWithLeader: 18, leaderState: 0, sliceStateWithLeader: 18}
+	d4 := &domain{id: "d4", state: 10, sliceState: 10, stateWithLeader: 10, leaderState: 0, sliceStateWithLeader: 10}
+	d5 := &domain{id: "d5", state: 2, sliceState: 2, stateWithLeader: 2, leaderState: 0, sliceStateWithLeader: 2}
+
+	testCases := map[string]struct {
+		domains     []*domain
+		sliceCount  int32
+		leaderCount int32
+		sliceSize   int32
+		threshold   int32
+		want        []*domain
+	}{
+		"simple balanced placement on two domains": {
+			domains:     []*domain{d1, d2, d3},
+			sliceCount:  20,
+			leaderCount: 0,
+			sliceSize:   1,
+			threshold:   10,
+			want: []*domain{
+				{id: "d1", sliceState: 10, state: 10, stateWithLeader: 10, sliceStateWithLeader: 10, leaderState: 0},
+				{id: "d2", sliceState: 10, state: 10, stateWithLeader: 10, sliceStateWithLeader: 10, leaderState: 0},
+			},
+		},
+		"simple placement on three domains": {
+			domains:     []*domain{d1, d2, d3},
+			sliceCount:  40,
+			leaderCount: 0,
+			sliceSize:   1,
+			threshold:   13,
+			want: []*domain{
+				{id: "d1", sliceState: 14, state: 14, stateWithLeader: 14, sliceStateWithLeader: 14, leaderState: 0},
+				{id: "d2", sliceState: 13, state: 13, stateWithLeader: 13, sliceStateWithLeader: 13, leaderState: 0},
+				{id: "d3", sliceState: 13, state: 13, stateWithLeader: 13, sliceStateWithLeader: 13, leaderState: 0},
+			},
+		},
+		"find smallest domain that fits": {
+			domains:     []*domain{d1, d2, d3, d4, d5},
+			sliceCount:  2,
+			leaderCount: 0,
+			sliceSize:   1,
+			threshold:   2,
+			want: []*domain{
+				{id: "d5", sliceState: 2, state: 2, stateWithLeader: 2, sliceStateWithLeader: 2, leaderState: 0},
+			},
+		},
+		"correctly select domains": {
+			domains:     []*domain{d1, d2, d3, d4, d5},
+			sliceCount:  25,
+			leaderCount: 0,
+			sliceSize:   1,
+			threshold:   10,
+			want: []*domain{
+				{id: "d1", sliceState: 15, state: 15, stateWithLeader: 15, sliceStateWithLeader: 15, leaderState: 0},
+				{id: "d4", sliceState: 10, state: 10, stateWithLeader: 10, sliceStateWithLeader: 10, leaderState: 0},
+			},
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			domains := make([]*domain, len(tc.domains))
+			_, log := utiltesting.ContextWithLog(t)
+			s := newTASFlavorSnapshot(log, "dummy", []string{}, nil)
+			for i, d := range tc.domains {
+				clone := *d
+				domains[i] = &clone
+			}
+
+			got, _ := placeSlicesOnDomainsBalanced(s, domains, tc.sliceCount, tc.leaderCount, tc.sliceSize, tc.threshold)
+
+			if diff := cmp.Diff(tc.want, got, cmp.AllowUnexported(domain{}), cmpopts.IgnoreFields(domain{}, "parent", "children", "levelValues"), cmpopts.SortSlices(func(a, b *domain) bool { return a.id < b.id })); diff != "" {
+				t.Errorf("Unexpected domains (-want,+got):\n%s", diff)
+			}
+		})
+	}
+}
diff --git a/pkg/cache/scheduler/tas_cache_test.go b/pkg/cache/scheduler/tas_cache_test.go
index 8e003b546..586dcb972 100644
--- a/pkg/cache/scheduler/tas_cache_test.go
+++ b/pkg/cache/scheduler/tas_cache_test.go
@@ -50,8 +50,9 @@ type PodSetTestCase struct {
 
 func TestFindTopologyAssignments(t *testing.T) {
 	const (
-		tasBlockLabel = "cloud.com/topology-block"
-		tasRackLabel  = "cloud.com/topology-rack"
+		tasBlockLabel    = "cloud.com/topology-block"
+		tasRackLabel     = "cloud.com/topology-rack"
+		tasSubBlockLabel = "cloud.com/topology-subblock"
 	)
 
 	//      b1                   b2
@@ -2786,6 +2787,1452 @@ func TestFindTopologyAssignments(t *testing.T) {
 				},
 			}},
 		},
+		//         b1
+		//       /  |
+		//     r1   r2
+		//    /     |
+		// x1:15   x2:15
+		// request: 25
+		// expected outcome: x1:13, x2:12
+		"balanced placement; basic": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred: ptr.To(tasRackLabel),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 25,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  13,
+							Values: []string{"x1"},
+						},
+						{
+							Count:  12,
+							Values: []string{"x2"},
+						},
+					},
+				},
+			}},
+		},
+		//        b1
+		//         |
+		//        r1
+		//    /    |    \
+		// x1:15, x2:13, x3:10
+		// request: 23
+		// expected outcome: x1:12, x2:11
+		"balanced placement; select optmial set of domains": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("23"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("13"),
+						corev1.ResourcePods: resource.MustParse("23"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("23"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred: ptr.To(tasRackLabel),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 23,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  12,
+							Values: []string{"x1"},
+						},
+						{
+							Count:  11,
+							Values: []string{"x2"},
+						},
+					},
+				},
+			}},
+		},
+		//        b1
+		//         |
+		//        r1
+		//    /    |    \
+		// x1:20, x2:15, x3:10
+		// request: 25
+		// sliceSize: 5
+		// expected outcome: x2:15, x3:10
+		"balanced placement; select optmial set of domains; with slices": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("20"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred:                   ptr.To(tasRackLabel),
+					PodSetSliceSize:             ptr.To(int32(5)),
+					PodSetSliceRequiredTopology: ptr.To(corev1.LabelHostname),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 25,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  15,
+							Values: []string{"x2"},
+						},
+						{
+							Count:  10,
+							Values: []string{"x3"},
+						},
+					},
+				},
+			}},
+		},
+		//         b1      b2
+		//         |       |
+		//        r1        r2
+		//    /     |      |    \
+		// x1:20   x2:10  x3:15   x4:15
+		// request: 22
+		// expected outcome: x3:11, x4:11
+		"balanced placement; select correct block": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("20"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r2-x3").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r2-x4").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred:       ptr.To(tasRackLabel),
+					PodSetSliceSize: ptr.To(int32(1)),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 22,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  11,
+							Values: []string{"x3"},
+						},
+						{
+							Count:  11,
+							Values: []string{"x4"},
+						},
+					},
+				},
+			}},
+		},
+		//         b1      b2
+		//         |       |
+		//        r1        r2
+		//    /     |      |    \
+		// x1:14   x2:11  x3:15   x4:10
+		// request: 25
+		// expected outcome: x1:14, x2:11
+		"balanced placement; cannot chose domains from different blocks": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("14"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("11"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r2-x3").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r2-x4").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred:       ptr.To(tasRackLabel),
+					PodSetSliceSize: ptr.To(int32(1)),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 25,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  14,
+							Values: []string{"x1"},
+						},
+						{
+							Count:  11,
+							Values: []string{"x2"},
+						},
+					},
+				},
+			}},
+		},
+		//          b1     b2
+		//        / |      |
+		//     r1   r2     r3
+		//    /     |      |    \
+		// x1:15   x2:15  x3:15   x4:15
+		// request: 25
+		// sizeSize: 5
+		// expected outcome: x3:15, x4:10
+		"balanced placement; select correct block; prefer blocks with single rack; with slices": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r3-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r3-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("25"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred:                   ptr.To(tasRackLabel),
+					PodSetSliceSize:             ptr.To(int32(5)),
+					PodSetSliceRequiredTopology: ptr.To(corev1.LabelHostname),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 25,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  15,
+							Values: []string{"x3"},
+						},
+						{
+							Count:  10,
+							Values: []string{"x4"},
+						},
+					},
+				},
+			}},
+		},
+		//           b1
+		//         /     \
+		//        sb1     sb2
+		//      /   |      |   \
+		//     r1   r2     r3   r4
+		//    /     |      |     |     \
+		// x1:18   x2:8    x3:15 x4:9  x5:7
+		// request: 20
+		// sliceSize: 2
+		// expected outcome: x3:10, x4:8, x5:2
+		"balanced placement; four level topology; slice two levels below balanced level": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-sb1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("18"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r2-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r3-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb2").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r3-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb2").
+					Label(tasRackLabel, "r4").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("9"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r3-x5").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb2").
+					Label(tasRackLabel, "r4").
+					Label(corev1.LabelHostname, "x5").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("7"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: []string{tasBlockLabel, tasSubBlockLabel, tasRackLabel, corev1.LabelHostname},
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred:                   ptr.To(string(tasSubBlockLabel)),
+					PodSetSliceSize:             ptr.To(int32(2)),
+					PodSetSliceRequiredTopology: ptr.To(corev1.LabelHostname),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 20,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: []string{corev1.LabelHostname},
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  10,
+							Values: []string{"x3"},
+						},
+						{
+							Count:  8,
+							Values: []string{"x4"},
+						},
+						{
+							Count:  2,
+							Values: []string{"x5"},
+						},
+					},
+				},
+			}},
+		},
+		//           b1
+		//         /     \
+		//        sb1     sb2
+		//      /   |      |   \
+		//     r1   r2     r3   r4
+		//    /     |      |     |     \
+		// x1:18   x2:8    x3:15 x4:9  x5:7
+		// request: 20
+		// expected outcome: x3:10, x4:3, x5:7
+		"balanced placement; four level topology; slice one level below balanced level": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-sb1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("18"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r2-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r3-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb2").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r3-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb2").
+					Label(tasRackLabel, "r4").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("9"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r3-x5").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb2").
+					Label(tasRackLabel, "r4").
+					Label(corev1.LabelHostname, "x5").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("7"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: []string{tasBlockLabel, tasSubBlockLabel, tasRackLabel, corev1.LabelHostname},
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred:                   ptr.To(string(tasSubBlockLabel)),
+					PodSetSliceSize:             ptr.To(int32(2)),
+					PodSetSliceRequiredTopology: ptr.To(tasRackLabel),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 20,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: []string{corev1.LabelHostname},
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  10,
+							Values: []string{"x3"},
+						},
+						{
+							Count:  3,
+							Values: []string{"x4"},
+						},
+						{
+							Count:  7,
+							Values: []string{"x5"},
+						},
+					},
+				},
+			}},
+		},
+		//           b1
+		//         /     \
+		//        sb1     sb2
+		//      /   |      | \
+		//     r1   r2     r3 r4
+		//    /     |      |     \
+		// x1:18   x2:8    x3:15 x4:15
+		// request: 20
+		// sliceSize: 2
+		// expected outcome: x3:10, x4:10
+		"balanced placement; four level topology; balance on rack level; slice not on the lowest level": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-sb1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("18"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r2-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r3-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb2").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-sb1-r3-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasSubBlockLabel, "sb2").
+					Label(tasRackLabel, "r4").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: []string{tasBlockLabel, tasSubBlockLabel, tasRackLabel},
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred:                   ptr.To(string(tasSubBlockLabel)),
+					PodSetSliceSize:             ptr.To(int32(2)),
+					PodSetSliceRequiredTopology: ptr.To(tasRackLabel),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 20,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: []string{tasBlockLabel, tasSubBlockLabel, tasRackLabel},
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  10,
+							Values: []string{"b1", "sb2", "r3"},
+						},
+						{
+							Count:  10,
+							Values: []string{"b1", "sb2", "r4"},
+						},
+					},
+				},
+			}},
+		},
+		//        b1
+		//         |        \
+		//        r1             r2
+		//    /    |    \         |     \
+		// x1:15, x2:13, x3:10   x4:20   x5:8
+		// request: 22
+		// sliceSize: 2
+		// expected outcome: x2:12, x3:10
+		"balanced placement; three level topology; balance on the same level as slice": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("13"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("20"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x5").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x5").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred:                   ptr.To(string(corev1.LabelHostname)),
+					PodSetSliceSize:             ptr.To(int32(2)),
+					PodSetSliceRequiredTopology: ptr.To(corev1.LabelHostname),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 22,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  12,
+							Values: []string{"x2"},
+						},
+						{
+							Count:  10,
+							Values: []string{"x3"},
+						},
+					},
+				},
+			}},
+		},
+		//        b1
+		//         |        \
+		//        r1             r2
+		//    /    |        /     |     \
+		// x1:20  x2:8  x3:15   x4:13   x5:10
+		// request: 22
+		// expected outcome: x3:11, x4:11
+		"balanced placement; three level topology; balance on the lowest level": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("20"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("13"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x5").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x5").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred: ptr.To(string(corev1.LabelHostname)),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 22,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  11,
+							Values: []string{"x3"},
+						},
+						{
+							Count:  11,
+							Values: []string{"x4"},
+						},
+					},
+				},
+			}},
+		},
+		//        b1
+		//         |
+		//        r1
+		//    /    |    \
+		// x1:20, x2:15, x3:12
+		// request: 25
+		// sliceSize: 5
+		// leaders: 1
+		// expected outcome: x2:15, x3:10 + leader
+		"balanced placement; leader worker set": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("20"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("15"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("12"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{
+				{
+					podSetName: "leader",
+					topologyRequest: &kueue.PodSetTopologyRequest{
+						Preferred:                   ptr.To(string(tasRackLabel)),
+						PodSetSliceRequiredTopology: ptr.To(corev1.LabelHostname),
+					},
+					requests: resources.Requests{
+						"example.com/gpu": 1,
+					},
+					podSetGroupName: ptr.To("sameGroup"),
+					count:           1,
+					wantAssignment: &kueue.TopologyAssignment{
+						Levels: defaultOneLevel,
+						Domains: []kueue.TopologyDomainAssignment{
+							{
+								Count:  1,
+								Values: []string{"x3"},
+							},
+						},
+					},
+				},
+				{
+					podSetName: "workers",
+					topologyRequest: &kueue.PodSetTopologyRequest{
+						Preferred:                   ptr.To(string(tasRackLabel)),
+						PodSetSliceSize:             ptr.To(int32(5)),
+						PodSetSliceRequiredTopology: ptr.To(corev1.LabelHostname),
+					},
+					requests: resources.Requests{
+						"example.com/gpu": 1,
+					},
+					podSetGroupName: ptr.To("sameGroup"),
+					count:           25,
+					wantAssignment: &kueue.TopologyAssignment{
+						Levels: defaultOneLevel,
+						Domains: []kueue.TopologyDomainAssignment{
+							{
+								Count:  15,
+								Values: []string{"x2"},
+							},
+							{
+								Count:  10,
+								Values: []string{"x3"},
+							},
+						},
+					},
+				},
+			},
+		},
+		//                  b1
+		//              /        \
+		//            r1         r2
+		//        /   |        /  |   \
+		//     x1:10 x2:5  x3:5  x4:5  x5:5
+		// request: 15
+		// expected outcome: x3:5, x4:5, x5:5
+		"balanced placement; prioritize (using entropy) balanced domains; second rack wins": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x5").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x5").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred: ptr.To(string(tasRackLabel)),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 15,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  5,
+							Values: []string{"x3"},
+						},
+						{
+							Count:  5,
+							Values: []string{"x4"},
+						},
+						{
+							Count:  5,
+							Values: []string{"x5"},
+						},
+					},
+				},
+			}},
+		},
+		//                  b1
+		//              /        \
+		//            r1          r2
+		//        /   |    \     |   \
+		//     x1:8 x2:8  x3:8  x4:16  x5:8
+		// request: 24
+		// expected outcome: x1:8, x2:8, x3:8
+		"balanced placement; prioritize (using entropy) balanced domains; first rack wins": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("16"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x5").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x5").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("8"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred: ptr.To(string(tasRackLabel)),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 24,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  8,
+							Values: []string{"x1"},
+						},
+						{
+							Count:  8,
+							Values: []string{"x2"},
+						},
+						{
+							Count:  8,
+							Values: []string{"x3"},
+						},
+					},
+				},
+			}},
+		},
+		//        r1             r2
+		//    /    |        /     |     \
+		// x1:21  x2:9  x3:11   x4:10   x5:10
+		// request: 23
+		// expected outcome: x1:12, x3:11
+		"balanced placement; two level topology; balance on the highest level": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("r1-x1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("21"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("r1-x2").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("9"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("r2-x3").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("11"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("r2-x4").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("r2-x5").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x5").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("22"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: []string{tasRackLabel, corev1.LabelHostname},
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred: ptr.To(string(tasRackLabel)),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 23,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  12,
+							Values: []string{"x1"},
+						},
+						{
+							Count:  11,
+							Values: []string{"x3"},
+						},
+					},
+				},
+			}},
+		},
+		//          b1                                b2
+		//        /      \                      /        |    \
+		//     r1         r2                r3           r4    r5
+		//    /  \       /   \        /   |    |    \     |    |
+		// x1:5  x2:5  x3:5   x4:5  x5:10 x6:4 x7:4 x8:4  x9:5 x10:5
+		// request: 20
+		// expected outcome: x1:5, x2:5, x3:5, x4:5
+		"balanced placement; select correct block taking into account pruning": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x3").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x3").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r2-x4").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r2").
+					Label(corev1.LabelHostname, "x4").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r3-x5").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x5").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("10"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r3-x6").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x6").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("4"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r3-x7").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x7").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("4"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r3-x8").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r3").
+					Label(corev1.LabelHostname, "x8").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("4"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r4-x9").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r4").
+					Label(corev1.LabelHostname, "x9").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b2-r5-x10").
+					Label(tasBlockLabel, "b2").
+					Label(tasRackLabel, "r5").
+					Label(corev1.LabelHostname, "x10").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("20"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{{
+				topologyRequest: &kueue.PodSetTopologyRequest{
+					Preferred: ptr.To(tasRackLabel),
+				},
+				requests: resources.Requests{
+					"example.com/gpu": 1,
+				},
+				count: 20,
+				wantAssignment: &kueue.TopologyAssignment{
+					Levels: defaultOneLevel,
+					Domains: []kueue.TopologyDomainAssignment{
+						{
+							Count:  5,
+							Values: []string{"x1"},
+						},
+						{
+							Count:  5,
+							Values: []string{"x2"},
+						},
+						{
+							Count:  5,
+							Values: []string{"x3"},
+						},
+						{
+							Count:  5,
+							Values: []string{"x4"},
+						},
+					},
+				},
+			}},
+		},
+		//        b1
+		//         |
+		//        r1
+		//    /    |
+		// x1:6  x2:5
+		// request: 10
+		// leaders: 1
+		// expected outcome: x1:5 + leader, x2:5
+		"balanced placement; should not prune domain": {
+			enableFeatureGates: []featuregate.Feature{features.TASBalancedPlacement},
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("6"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label(tasBlockLabel, "b1").
+					Label(tasRackLabel, "r1").
+					Label(corev1.LabelHostname, "x2").
+					StatusAllocatable(corev1.ResourceList{
+						"example.com/gpu":   resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("24"),
+					}).
+					Ready().
+					Obj(),
+			},
+			levels: defaultThreeLevels,
+			podSets: []PodSetTestCase{
+				{
+					podSetName: "leader",
+					topologyRequest: &kueue.PodSetTopologyRequest{
+						Preferred:                   ptr.To(string(tasRackLabel)),
+						PodSetSliceRequiredTopology: ptr.To(corev1.LabelHostname),
+					},
+					requests: resources.Requests{
+						"example.com/gpu": 1,
+					},
+					podSetGroupName: ptr.To("sameGroup"),
+					count:           1,
+					wantAssignment: &kueue.TopologyAssignment{
+						Levels: defaultOneLevel,
+						Domains: []kueue.TopologyDomainAssignment{
+							{
+								Count:  1,
+								Values: []string{"x1"},
+							},
+						},
+					},
+				},
+				{
+					podSetName: "workers",
+					topologyRequest: &kueue.PodSetTopologyRequest{
+						Preferred: ptr.To(string(tasRackLabel)),
+					},
+					requests: resources.Requests{
+						"example.com/gpu": 1,
+					},
+					podSetGroupName: ptr.To("sameGroup"),
+					count:           10,
+					wantAssignment: &kueue.TopologyAssignment{
+						Levels: defaultOneLevel,
+						Domains: []kueue.TopologyDomainAssignment{
+							{
+								Count:  5,
+								Values: []string{"x1"},
+							},
+							{
+								Count:  5,
+								Values: []string{"x2"},
+							},
+						},
+					},
+				},
+			},
+		},
 		"block required for podset; rack required for slices; podset fits in a block, but slices do not fit in racks": {
 
 			//         b1
diff --git a/pkg/controller/jobframework/reconciler_test.go b/pkg/controller/jobframework/reconciler_test.go
index 26592bd7d..315196b52 100644
--- a/pkg/controller/jobframework/reconciler_test.go
+++ b/pkg/controller/jobframework/reconciler_test.go
@@ -17,6 +17,8 @@ limitations under the License.
 package jobframework_test
 
 import (
+	"context"
+	"errors"
 	"testing"
 	"time"
 
@@ -28,6 +30,7 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	batchv1 "k8s.io/api/batch/v1"
 	corev1 "k8s.io/api/core/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/utils/clock"
@@ -35,6 +38,7 @@ import (
 	"k8s.io/utils/ptr"
 	controllerruntime "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/client/interceptor"
 	"sigs.k8s.io/jobset/api/jobset/v1alpha2"
 
 	configapi "sigs.k8s.io/kueue/apis/config/v1beta2"
@@ -42,6 +46,7 @@ import (
 	mocks "sigs.k8s.io/kueue/internal/mocks/controller/jobframework"
 	"sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/controller/core/indexer"
+	"sigs.k8s.io/kueue/pkg/controller/jobs/job"
 	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/util/kubeversion"
 	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
@@ -709,3 +714,137 @@ func TestProcessOptions(t *testing.T) {
 		})
 	}
 }
+
+func TestReconcileGenericJobWithWaitForPodsReady(t *testing.T) {
+	var (
+		testLocalQueueName = kueue.LocalQueueName("default")
+		testGVK            = batchv1.SchemeGroupVersion.WithKind("Job")
+	)
+	testCases := map[string]struct {
+		workload  *kueue.Workload
+		job       GenericJob
+		wantError error
+	}{
+		"update podready condition failed": {
+			workload: utiltestingapi.MakeWorkload("job-test-job-podready-fail", metav1.NamespaceDefault).
+				Finalizers(kueue.ResourceInUseFinalizerName).
+				Label(constants.JobUIDLabel, "test-job-podready-fail").
+				ControllerReference(testGVK, "test-job-podready-fail", "test-job-podready-fail").
+				Queue(testLocalQueueName).
+				PodSets(*utiltestingapi.MakePodSet("main", 1).Obj()).
+				Conditions(metav1.Condition{
+					Type:               kueue.WorkloadAdmitted,
+					Status:             metav1.ConditionTrue,
+					Reason:             "Admitted",
+					Message:            "The workload is admitted",
+					LastTransitionTime: metav1.NewTime(time.Now()),
+				}, metav1.Condition{
+					Type:               kueue.WorkloadPodsReady,
+					Status:             metav1.ConditionFalse,
+					Reason:             kueue.WorkloadWaitForStart,
+					Message:            "Not all pods are ready or succeeded",
+					LastTransitionTime: metav1.NewTime(time.Now()),
+				}).
+				Admission(&kueue.Admission{
+					ClusterQueue: "default-cq",
+				}).
+				Obj(),
+			job: (*job.Job)(testingjob.MakeJob("test-job-podready-fail", metav1.NamespaceDefault).
+				UID("test-job-podready-fail").
+				Label(constants.QueueLabel, string(testLocalQueueName)).
+				Parallelism(1).
+				Suspend(false).
+				Containers(corev1.Container{
+					Name: "c",
+					Resources: corev1.ResourceRequirements{
+						Requests: make(corev1.ResourceList),
+					},
+				}).
+				Ready(1).
+				Obj()),
+			wantError: apierrors.NewInternalError(errors.New("failed calling webhook")),
+		},
+		"update podready condition success": {
+			workload: utiltestingapi.MakeWorkload("job-test-job-podready-success", metav1.NamespaceDefault).
+				Finalizers(kueue.ResourceInUseFinalizerName).
+				Label(constants.JobUIDLabel, "job-test-job-podready-success").
+				ControllerReference(testGVK, "test-job-podready-success", "test-job-podready-success").
+				Queue(testLocalQueueName).
+				PodSets(*utiltestingapi.MakePodSet("main", 1).Obj()).
+				Conditions(metav1.Condition{
+					Type:               kueue.WorkloadAdmitted,
+					Status:             metav1.ConditionTrue,
+					Reason:             "Admitted",
+					Message:            "The workload is admitted",
+					LastTransitionTime: metav1.NewTime(time.Now()),
+				}, metav1.Condition{
+					Type:               kueue.WorkloadPodsReady,
+					Status:             metav1.ConditionFalse,
+					Reason:             kueue.WorkloadWaitForStart,
+					Message:            "Not all pods are ready or succeeded",
+					LastTransitionTime: metav1.NewTime(time.Now()),
+				}).
+				Admission(&kueue.Admission{
+					ClusterQueue: "default-cq",
+				}).
+				Obj(),
+			job: (*job.Job)(testingjob.MakeJob("test-job-podready-success", metav1.NamespaceDefault).
+				UID("test-job-podready-success").
+				Label(constants.QueueLabel, string(testLocalQueueName)).
+				Parallelism(1).
+				Suspend(false).
+				Containers(corev1.Container{
+					Name: "c",
+					Resources: corev1.ResourceRequirements{
+						Requests: make(corev1.ResourceList),
+					},
+				}).
+				Ready(1).
+				Obj()),
+			wantError: nil,
+		},
+	}
+
+	for name, tc := range testCases {
+		t.Run(name, func(t *testing.T) {
+			ctx, _ := utiltesting.ContextWithLog(t)
+			managedNamespace := utiltesting.MakeNamespaceWrapper(metav1.NamespaceDefault).
+				Label("managed-by-kueue", "true").
+				Obj()
+			builder := utiltesting.NewClientBuilder(batchv1.AddToScheme, kueue.AddToScheme).
+				WithObjects(tc.workload, tc.job.Object(), managedNamespace).
+				WithStatusSubresource(tc.workload, tc.job.Object()).
+				WithIndex(&kueue.Workload{}, indexer.OwnerReferenceIndexKey(testGVK), indexer.WorkloadOwnerIndexFunc(testGVK)).
+				WithInterceptorFuncs(interceptor.Funcs{
+					SubResourcePatch: func(ctx context.Context, client client.Client, subResourceName string, obj client.Object, patch client.Patch, opts ...client.SubResourcePatchOption) error {
+						if _, ok := obj.(*kueue.Workload); ok && subResourceName == "status" && tc.wantError != nil {
+							return tc.wantError
+						}
+						return utiltesting.TreatSSAAsStrategicMerge(ctx, client, subResourceName, obj, patch, opts...)
+					},
+				})
+
+			cl := builder.Build()
+
+			testStartTime := time.Now().Truncate(time.Second)
+
+			fakeClock := testingclock.NewFakeClock(testStartTime)
+			options := []Option{
+				WithClock(nil, fakeClock),
+				WithWaitForPodsReady(&configapi.WaitForPodsReady{
+					Enable: true,
+				}),
+			}
+			recorder := &utiltesting.EventRecorder{}
+			r := NewReconciler(cl, recorder, options...)
+			_, err := r.ReconcileGenericJob(ctx, controllerruntime.Request{
+				NamespacedName: types.NamespacedName{
+					Name:      tc.job.Object().GetName(),
+					Namespace: tc.job.Object().GetNamespace(),
+				}}, tc.job)
+			if !errors.Is(err, tc.wantError) {
+				t.Errorf("unexpected reconcile error want %s got %s)", tc.wantError, err)
+			}
+		})
+	}
+}
diff --git a/pkg/controller/jobs/job/job_controller_test.go b/pkg/controller/jobs/job/job_controller_test.go
index fc02ee2ba..89115e213 100644
--- a/pkg/controller/jobs/job/job_controller_test.go
+++ b/pkg/controller/jobs/job/job_controller_test.go
@@ -38,7 +38,6 @@ import (
 
 	configapi "sigs.k8s.io/kueue/apis/config/v1beta2"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/constants"
 	controllerconsts "sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobframework"
 	"sigs.k8s.io/kueue/pkg/features"
@@ -2689,8 +2688,7 @@ func TestReconciler(t *testing.T) {
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").Obj()).
 					Queue("foo").
 					Priority(baseWPCWrapper.Value).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
-					PriorityClass(baseWPCWrapper.Name).
+					WorkloadPriorityClassRef(baseWPCWrapper.Name).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
@@ -2702,8 +2700,7 @@ func TestReconciler(t *testing.T) {
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").Obj()).
 					Queue("foo").
 					Priority(highWPCWrapper.Value).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
-					PriorityClass(highWPCWrapper.Name).
+					WorkloadPriorityClassRef(highWPCWrapper.Name).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
@@ -2739,8 +2736,7 @@ func TestReconciler(t *testing.T) {
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).PriorityClass(basePCWrapper.Name).Request(corev1.ResourceCPU, "1").Obj()).
 					Queue("foo").
 					Priority(basePCWrapper.Value).
-					PriorityClassSource(constants.PodPriorityClassSource).
-					PriorityClass(basePCWrapper.Name).
+					PodPriorityClassRef(basePCWrapper.Name).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
@@ -2752,8 +2748,7 @@ func TestReconciler(t *testing.T) {
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).PriorityClass(basePCWrapper.Name).Request(corev1.ResourceCPU, "1").Obj()).
 					Queue("foo").
 					Priority(basePCWrapper.Value).
-					PriorityClassSource(constants.PodPriorityClassSource).
-					PriorityClass(basePCWrapper.Name).
+					PodPriorityClassRef(basePCWrapper.Name).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
@@ -3185,9 +3180,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
@@ -3230,9 +3224,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").PriorityClass("test-pc").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-pc").
+					PodPriorityClassRef("test-pc").
 					Priority(200).
-					PriorityClassSource(constants.PodPriorityClassSource).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
@@ -3277,9 +3270,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").PriorityClass("test-pc").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
@@ -3349,9 +3341,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").PriorityClass("test-pc").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					Obj(),
 			},
 			wantWorkloads: []kueue.Workload{
@@ -3359,9 +3350,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").PriorityClass("test-pc").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
@@ -3394,9 +3384,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").PriorityClass("test-pc").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					ControllerReference(batchv1.SchemeGroupVersion.WithKind("Job"), "other-job", "other-uid").
 					Obj(),
 			},
@@ -3405,9 +3394,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 10).Request(corev1.ResourceCPU, "1").PriorityClass("test-pc").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					ControllerReference(batchv1.SchemeGroupVersion.WithKind("Job"), "other-job", "other-uid").
 					Obj(),
 			},
@@ -3438,9 +3426,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 1).Request(corev1.ResourceCPU, "1").PriorityClass("test-pc").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					Obj(),
 			},
 			wantWorkloads: []kueue.Workload{
@@ -3448,9 +3435,8 @@ func TestReconciler(t *testing.T) {
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 1).Request(corev1.ResourceCPU, "1").PriorityClass("test-pc").Obj()).
 					Queue("test-queue").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					Labels(map[string]string{
 						controllerconsts.JobUIDLabel: "test-uid",
 					}).
diff --git a/pkg/controller/jobs/jobset/jobset_controller_test.go b/pkg/controller/jobs/jobset/jobset_controller_test.go
index b033317de..96dee2e6e 100644
--- a/pkg/controller/jobs/jobset/jobset_controller_test.go
+++ b/pkg/controller/jobs/jobset/jobset_controller_test.go
@@ -32,7 +32,6 @@ import (
 	jobset "sigs.k8s.io/jobset/api/jobset/v1alpha2"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/constants"
 	controllerconsts "sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobframework"
 	"sigs.k8s.io/kueue/pkg/features"
@@ -473,9 +472,8 @@ func TestReconciler(t *testing.T) {
 			).WorkloadPriorityClass("test-wpc").Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltestingapi.MakeWorkload("jobset", "ns").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					PodSets(
 						*utiltestingapi.MakePodSet("replicated-job-1", 1).
 							PodIndexLabel(ptr.To("batch.kubernetes.io/job-completion-index")).
@@ -512,9 +510,8 @@ func TestReconciler(t *testing.T) {
 			).PriorityClass("test-pc").Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltestingapi.MakeWorkload("jobset", "ns").
-					PriorityClass("test-pc").
+					PodPriorityClassRef("test-pc").
 					Priority(200).
-					PriorityClassSource(constants.PodPriorityClassSource).
 					PodSets(
 						*utiltestingapi.MakePodSet("replicated-job-1", 1).
 							PodIndexLabel(ptr.To("batch.kubernetes.io/job-completion-index")).
@@ -551,9 +548,8 @@ func TestReconciler(t *testing.T) {
 			).PriorityClass("test-pc").WorkloadPriorityClass("test-wpc").Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltestingapi.MakeWorkload("jobset", "ns").
-					PriorityClass("test-wpc").
+					WorkloadPriorityClassRef("test-wpc").
 					Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					PodSets(
 						*utiltestingapi.MakePodSet("replicated-job-1", 1).
 							PodIndexLabel(ptr.To("batch.kubernetes.io/job-completion-index")).
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
index 2fbe671eb..63e5ed9df 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
@@ -32,7 +32,6 @@ import (
 	leaderworkersetv1 "sigs.k8s.io/lws/api/leaderworkerset/v1"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobframework"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
 	"sigs.k8s.io/kueue/pkg/features"
@@ -533,9 +532,8 @@ func TestReconciler(t *testing.T) {
 							Count:           1,
 							TopologyRequest: nil,
 						}).
-					PriorityClass("high-priority").
+					WorkloadPriorityClassRef("high-priority").
 					Priority(5000).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
 					Obj(),
 			},
 			wantEvents: []utiltesting.EventRecord{
diff --git a/pkg/controller/jobs/mpijob/mpijob_controller_test.go b/pkg/controller/jobs/mpijob/mpijob_controller_test.go
index 2fb69af05..1c752ada5 100644
--- a/pkg/controller/jobs/mpijob/mpijob_controller_test.go
+++ b/pkg/controller/jobs/mpijob/mpijob_controller_test.go
@@ -31,7 +31,6 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobframework"
 	"sigs.k8s.io/kueue/pkg/features"
 	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
@@ -408,8 +407,9 @@ func TestReconciler(t *testing.T) {
 						*utiltestingapi.MakePodSet("worker", 2).
 							PodIndexLabel(ptr.To(kfmpi.ReplicaIndexLabel)).
 							Obj(),
-					).PriorityClass("test-wpc").Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
+					).
+					WorkloadPriorityClassRef("test-wpc").
+					Priority(100).
 					Obj(),
 			},
 		},
@@ -432,8 +432,9 @@ func TestReconciler(t *testing.T) {
 						*utiltestingapi.MakePodSet("worker", 2).
 							PodIndexLabel(ptr.To(kfmpi.ReplicaIndexLabel)).
 							Obj(),
-					).PriorityClass("test-pc").Priority(200).
-					PriorityClassSource(constants.PodPriorityClassSource).
+					).
+					PodPriorityClassRef("test-pc").
+					Priority(200).
 					Obj(),
 			},
 		},
@@ -458,8 +459,9 @@ func TestReconciler(t *testing.T) {
 						*utiltestingapi.MakePodSet("worker", 2).
 							PodIndexLabel(ptr.To(kfmpi.ReplicaIndexLabel)).
 							Obj(),
-					).PriorityClass("test-wpc").Priority(100).
-					PriorityClassSource(constants.WorkloadPriorityClassSource).
+					).
+					WorkloadPriorityClassRef("test-wpc").
+					Priority(100).
 					Obj(),
 			},
 		},
diff --git a/pkg/controller/jobs/trainjob/trainjob_controller_test.go b/pkg/controller/jobs/trainjob/trainjob_controller_test.go
index 837edec15..5438f94a8 100644
--- a/pkg/controller/jobs/trainjob/trainjob_controller_test.go
+++ b/pkg/controller/jobs/trainjob/trainjob_controller_test.go
@@ -360,6 +360,7 @@ func TestReconciler(t *testing.T) {
 			Name:        "node",
 			Replicas:    1,
 			Parallelism: 1,
+			Completions: 1,
 		}).Obj()
 	testCtr := testingtrainjob.MakeClusterTrainingRuntime("test", testJobset.Spec)
 
diff --git a/pkg/controller/jobs/trainjob/trainjob_webhook_test.go b/pkg/controller/jobs/trainjob/trainjob_webhook_test.go
index b78a9a33d..56e6c7d13 100644
--- a/pkg/controller/jobs/trainjob/trainjob_webhook_test.go
+++ b/pkg/controller/jobs/trainjob/trainjob_webhook_test.go
@@ -55,6 +55,7 @@ func TestValidateCreate(t *testing.T) {
 				Name:        "node",
 				Replicas:    1,
 				Parallelism: 1,
+				Completions: 1,
 			}).Obj().Spec)
 	testTrainJob := testingtrainjob.MakeTrainJob("trainjob", "ns").RuntimeRef(kftrainerapi.RuntimeRef{
 		APIGroup: ptr.To(kftrainerapi.GroupVersion.Group),
diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go
index 4f93d61c5..5f579d2e2 100644
--- a/pkg/scheduler/scheduler_test.go
+++ b/pkg/scheduler/scheduler_test.go
@@ -6872,6 +6872,7 @@ func TestSchedule(t *testing.T) {
 						Status:             metav1.ConditionTrue,
 						Reason:             kueue.WorkloadSliceReplaced,
 						Message:            "Replaced to accommodate a workload (UID: , JobUID: ) due to workload slice aggregation",
+						ObservedGeneration: 1,
 						LastTransitionTime: metav1.NewTime(now),
 					}).
 					Obj(),
diff --git a/pkg/util/priority/priority_test.go b/pkg/util/priority/priority_test.go
index 6d8f005d5..26ca76df6 100644
--- a/pkg/util/priority/priority_test.go
+++ b/pkg/util/priority/priority_test.go
@@ -66,12 +66,11 @@ func TestGetPriorityFromPriorityClass(t *testing.T) {
 	}
 
 	tests := map[string]struct {
-		priorityClassList       *schedulingv1.PriorityClassList
-		priorityClassName       string
-		wantPriorityClassName   string
-		wantPriorityClassSource string
-		wantPriorityClassValue  int32
-		wantErr                 error
+		priorityClassList      *schedulingv1.PriorityClassList
+		priorityClassName      string
+		wantPriorityClassRef   *kueue.PriorityClassRef
+		wantPriorityClassValue int32
+		wantErr                error
 	}{
 		"priorityClass is specified and it exists": {
 			priorityClassList: &schedulingv1.PriorityClassList{
@@ -82,10 +81,10 @@ func TestGetPriorityFromPriorityClass(t *testing.T) {
 					},
 				},
 			},
-			priorityClassName:       "test",
-			wantPriorityClassSource: constants.PodPriorityClassSource,
-			wantPriorityClassName:   "test",
-			wantPriorityClassValue:  50,
+
+			priorityClassName:      "test",
+			wantPriorityClassRef:   kueue.NewPodPriorityClassRef("test"),
+			wantPriorityClassValue: 50,
 		},
 		"priorityClass is specified and it does not exist": {
 			priorityClassList: &schedulingv1.PriorityClassList{
@@ -104,9 +103,8 @@ func TestGetPriorityFromPriorityClass(t *testing.T) {
 					},
 				},
 			},
-			wantPriorityClassName:   "globalDefault",
-			wantPriorityClassSource: constants.PodPriorityClassSource,
-			wantPriorityClassValue:  40,
+			wantPriorityClassRef:   kueue.NewPodPriorityClassRef("globalDefault"),
+			wantPriorityClassValue: 40,
 		},
 		"priorityClass is unspecified and multiple global defaults exist": {
 			priorityClassList: &schedulingv1.PriorityClassList{
@@ -128,9 +126,8 @@ func TestGetPriorityFromPriorityClass(t *testing.T) {
 					},
 				},
 			},
-			wantPriorityClassName:   "globalDefault2",
-			wantPriorityClassSource: constants.PodPriorityClassSource,
-			wantPriorityClassValue:  20,
+			wantPriorityClassRef:   kueue.NewPodPriorityClassRef("globalDefault2"),
+			wantPriorityClassValue: 20,
 		},
 	}
 
@@ -142,17 +139,13 @@ func TestGetPriorityFromPriorityClass(t *testing.T) {
 			client := builder.Build()
 
 			ctx, _ := utiltesting.ContextWithLog(t)
-			name, source, value, err := GetPriorityFromPriorityClass(ctx, client, tt.priorityClassName)
+			priorityClassRef, value, err := GetPriorityFromPriorityClass(ctx, client, tt.priorityClassName)
 			if diff := cmp.Diff(tt.wantErr, err); diff != "" {
 				t.Errorf("unexpected error (-want,+got):\n%s", diff)
 			}
 
-			if name != tt.wantPriorityClassName {
-				t.Errorf("unexpected name: got: %s, expected: %s", name, tt.wantPriorityClassName)
-			}
-
-			if source != tt.wantPriorityClassSource {
-				t.Errorf("unexpected source: got: %s, expected: %s", source, tt.wantPriorityClassSource)
+			if diff := cmp.Diff(tt.wantPriorityClassRef, priorityClassRef); diff != "" {
+				t.Errorf("unexpected priortyClassRef (-want,+got):\n%s", diff)
 			}
 
 			if value != tt.wantPriorityClassValue {
@@ -169,12 +162,11 @@ func TestGetPriorityFromWorkloadPriorityClass(t *testing.T) {
 	}
 
 	tests := map[string]struct {
-		workloadPriorityClassList       *kueue.WorkloadPriorityClassList
-		workloadPriorityClassName       string
-		wantWorkloadPriorityClassName   string
-		wantWorkloadPriorityClassSource string
-		wantWorkloadPriorityClassValue  int32
-		wantErr                         error
+		workloadPriorityClassList *kueue.WorkloadPriorityClassList
+		workloadPriorityClassName string
+		wantPriorityClassRef      *kueue.PriorityClassRef
+		wantPriorityClassValue    int32
+		wantErr                   error
 	}{
 		"workloadPriorityClass is specified and it exists": {
 			workloadPriorityClassList: &kueue.WorkloadPriorityClassList{
@@ -185,10 +177,9 @@ func TestGetPriorityFromWorkloadPriorityClass(t *testing.T) {
 					},
 				},
 			},
-			workloadPriorityClassName:       "test",
-			wantWorkloadPriorityClassSource: constants.WorkloadPriorityClassSource,
-			wantWorkloadPriorityClassName:   "test",
-			wantWorkloadPriorityClassValue:  50,
+			workloadPriorityClassName: "test",
+			wantPriorityClassRef:      kueue.NewWorkloadPriorityClassRef("test"),
+			wantPriorityClassValue:    50,
 		},
 		"workloadPriorityClass is specified and it does not exist": {
 			workloadPriorityClassList: &kueue.WorkloadPriorityClassList{
@@ -206,21 +197,17 @@ func TestGetPriorityFromWorkloadPriorityClass(t *testing.T) {
 			builder := fake.NewClientBuilder().WithScheme(scheme).WithLists(tt.workloadPriorityClassList)
 			client := builder.Build()
 			ctx, _ := utiltesting.ContextWithLog(t)
-			name, source, value, err := GetPriorityFromWorkloadPriorityClass(ctx, client, tt.workloadPriorityClassName)
+			priorityClassRef, value, err := GetPriorityFromWorkloadPriorityClass(ctx, client, tt.workloadPriorityClassName)
 			if diff := cmp.Diff(tt.wantErr, err); diff != "" {
 				t.Errorf("unexpected error (-want,+got):\n%s", diff)
 			}
 
-			if name != tt.wantWorkloadPriorityClassName {
-				t.Errorf("unexpected name: got: %s, expected: %s", name, tt.wantWorkloadPriorityClassName)
+			if diff := cmp.Diff(tt.wantPriorityClassRef, priorityClassRef); diff != "" {
+				t.Errorf("unexpected priortyClassRef (-want,+got):\n%s", diff)
 			}
 
-			if source != tt.wantWorkloadPriorityClassSource {
-				t.Errorf("unexpected source: got: %s, expected: %s", source, tt.wantWorkloadPriorityClassSource)
-			}
-
-			if value != tt.wantWorkloadPriorityClassValue {
-				t.Errorf("unexpected value: got: %d, expected: %d", value, tt.wantWorkloadPriorityClassValue)
+			if value != tt.wantPriorityClassValue {
+				t.Errorf("unexpected value: got: %d, expected: %d", value, tt.wantPriorityClassValue)
 			}
 		})
 	}
diff --git a/pkg/util/testing/v1beta2/wrappers.go b/pkg/util/testing/v1beta2/wrappers.go
index ff7d5a615..6c2198efd 100644
--- a/pkg/util/testing/v1beta2/wrappers.go
+++ b/pkg/util/testing/v1beta2/wrappers.go
@@ -238,11 +238,6 @@ func (w *WorkloadWrapper) Creation(t time.Time) *WorkloadWrapper {
 	return w
 }
 
-func (w *WorkloadWrapper) PriorityClass(priorityClassName string) *WorkloadWrapper {
-	w.Spec.PriorityClassName = priorityClassName
-	return w
-}
-
 func (w *WorkloadWrapper) RuntimeClass(name string) *WorkloadWrapper {
 	for i := range w.Spec.PodSets {
 		w.Spec.PodSets[i].Template.Spec.RuntimeClassName = &name
@@ -250,13 +245,21 @@ func (w *WorkloadWrapper) RuntimeClass(name string) *WorkloadWrapper {
 	return w
 }
 
-func (w *WorkloadWrapper) Priority(priority int32) *WorkloadWrapper {
-	w.Spec.Priority = &priority
+func (w *WorkloadWrapper) PriorityClassRef(ref *kueue.PriorityClassRef) *WorkloadWrapper {
+	w.Spec.PriorityClassRef = ref
 	return w
 }
 
-func (w *WorkloadWrapper) PriorityClassSource(source string) *WorkloadWrapper {
-	w.Spec.PriorityClassSource = source
+func (w *WorkloadWrapper) WorkloadPriorityClassRef(name string) *WorkloadWrapper {
+	return w.PriorityClassRef(kueue.NewWorkloadPriorityClassRef(name))
+}
+
+func (w *WorkloadWrapper) PodPriorityClassRef(name string) *WorkloadWrapper {
+	return w.PriorityClassRef(kueue.NewPodPriorityClassRef(name))
+}
+
+func (w *WorkloadWrapper) Priority(priority int32) *WorkloadWrapper {
+	w.Spec.Priority = &priority
 	return w
 }
 
diff --git a/pkg/workloadslicing/workloadslicing_test.go b/pkg/workloadslicing/workloadslicing_test.go
index ac4394559..b1fefabce 100644
--- a/pkg/workloadslicing/workloadslicing_test.go
+++ b/pkg/workloadslicing/workloadslicing_test.go
@@ -347,7 +347,9 @@ func TestFinish(t *testing.T) {
 			args: args{
 				clnt: testWorkloadClientBuilder().
 					WithObjects(testWorkload("test", "test-job", "job-uid", now).Obj()).
-					WithStatusSubresource(testWorkload("test", "test-job", "job-uid", now).Obj()).Build(),
+					WithStatusSubresource(testWorkload("test", "test-job", "job-uid", now).Obj()).
+					WithInterceptorFuncs(interceptor.Funcs{SubResourcePatch: utiltesting.TreatSSAAsStrategicMerge}).
+					Build(),
 				workloadSlice: testWorkload("test", "test-job", "job-uid", now).Obj(),
 				reason:        "TestReason",
 				message:       "Test Message.",
@@ -831,6 +833,7 @@ func TestEnsureWorkloadSlices(t *testing.T) {
 						Creation(now).
 						PodSets(*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 3).Request(corev1.ResourceCPU, "1").Obj()).
 						Obj()).
+					WithInterceptorFuncs(interceptor.Funcs{SubResourcePatch: utiltesting.TreatSSAAsStrategicMerge}).
 					Build(),
 				jobPodSets:   []kueue.PodSet{*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 5).Request(corev1.ResourceCPU, "1").Obj()},
 				jobObject:    testJobObject,
diff --git a/test/e2e/certmanager/certmanager_test.go b/test/e2e/certmanager/certmanager_test.go
index 2aa7a582f..0ec8c6b70 100644
--- a/test/e2e/certmanager/certmanager_test.go
+++ b/test/e2e/certmanager/certmanager_test.go
@@ -68,6 +68,7 @@ var _ = ginkgo.Describe("CertManager", ginkgo.Ordered, func() {
 		ginkgo.It("should admit a Job", func() {
 			testJob := testingjob.MakeJob("test-job", ns.Name).
 				Queue("main").
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				Suspend(false).
 				Obj()
 			util.MustCreate(ctx, k8sClient, testJob)
diff --git a/test/e2e/customconfigs/managejobswithoutqueuename_test.go b/test/e2e/customconfigs/managejobswithoutqueuename_test.go
index a3b925011..2250a9efe 100644
--- a/test/e2e/customconfigs/managejobswithoutqueuename_test.go
+++ b/test/e2e/customconfigs/managejobswithoutqueuename_test.go
@@ -42,7 +42,7 @@ import (
 	"sigs.k8s.io/kueue/pkg/controller/jobs/statefulset"
 	"sigs.k8s.io/kueue/pkg/features"
 	utilpod "sigs.k8s.io/kueue/pkg/util/pod"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	awtesting "sigs.k8s.io/kueue/pkg/util/testingjobs/appwrapper"
 	testingdeploy "sigs.k8s.io/kueue/pkg/util/testingjobs/deployment"
@@ -523,7 +523,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("deleting the pod", func() {
 				gomega.Expect(k8sClient.Delete(ctx, testPod)).Should(gomega.Succeed())
 				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, podLookupKey, createdPod)).Should(testing.BeNotFoundError())
+					g.Expect(k8sClient.Get(ctx, podLookupKey, createdPod)).Should(utiltesting.BeNotFoundError())
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -608,7 +608,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("check that workload is created and not admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, createdWorkload)).To(gomega.Succeed())
-					g.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatusFalse(kueue.WorkloadQuotaReserved))
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusFalse(kueue.WorkloadQuotaReserved))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -647,7 +647,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("check that workload is admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, createdWorkload)).To(gomega.Succeed())
-					g.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -742,7 +742,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 			ginkgo.By("verifying that the Deployment doesn't create", func() {
 				createdDeployment := &appsv1.Deployment{}
 				gomega.Consistently(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, deploymentKey, createdDeployment)).To(testing.BeNotFoundError())
+					g.Expect(k8sClient.Get(ctx, deploymentKey, createdDeployment)).To(utiltesting.BeNotFoundError())
 				}, util.ConsistentDuration, util.ShortInterval).Should(gomega.Succeed())
 			})
 
@@ -769,7 +769,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 					g.Expect(k8sClient.List(ctx, createdWorkloads, client.InNamespace(aw.Namespace))).To(gomega.Succeed())
 					g.Expect(createdWorkloads.Items).To(gomega.HaveLen(1))
 					g.Expect(createdWorkloads.Items[0].Name).To(gomega.Equal(appwrapper.GetWorkloadNameForAppWrapper(aw.Name, aw.UID)))
-					g.Expect(createdWorkloads.Items[0].Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdWorkloads.Items[0].Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -801,7 +801,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 					g.Expect(k8sClient.List(ctx, createdWorkloads, client.InNamespace(lws.Namespace))).To(gomega.Succeed())
 					g.Expect(createdWorkloads.Items).To(gomega.HaveLen(1))
 					g.Expect(createdWorkloads.Items[0].Name).To(gomega.Equal(leaderworkerset.GetWorkloadName(lws.UID, lws.Name, "0")))
-					g.Expect(createdWorkloads.Items[0].Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdWorkloads.Items[0].Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 					util.MustHaveOwnerReference(g, createdWorkloads.Items[0].OwnerReferences, lws, k8sClient.Scheme())
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -811,7 +811,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrue("Available"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrue("Available"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -838,7 +838,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 					}
 					createdWorkload := &kueue.Workload{}
 					gomega.Eventually(func(g gomega.Gomega) {
-						g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(testing.BeNotFoundError())
+						g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(utiltesting.BeNotFoundError())
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 			})
@@ -862,7 +862,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 					g.Expect(k8sClient.List(ctx, createdWorkloads, client.InNamespace(lws.Namespace))).To(gomega.Succeed())
 					g.Expect(createdWorkloads.Items).To(gomega.HaveLen(1))
 					g.Expect(createdWorkloads.Items[0].Name).To(gomega.Equal(leaderworkerset.GetWorkloadName(lws.UID, lws.Name, "0")))
-					g.Expect(createdWorkloads.Items[0].Status.Conditions).To(testing.HaveConditionStatusFalse(kueue.WorkloadQuotaReserved))
+					g.Expect(createdWorkloads.Items[0].Status.Conditions).To(utiltesting.HaveConditionStatusFalse(kueue.WorkloadQuotaReserved))
 					util.MustHaveOwnerReference(g, createdWorkloads.Items[0].OwnerReferences, lws, k8sClient.Scheme())
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -900,7 +900,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 				}
 				createdWorkload := &kueue.Workload{}
 				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(testing.BeNotFoundError())
+					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(utiltesting.BeNotFoundError())
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
diff --git a/test/e2e/customconfigs/objectretentionpolicies_test.go b/test/e2e/customconfigs/objectretentionpolicies_test.go
index 05a150ba1..8002aea3e 100644
--- a/test/e2e/customconfigs/objectretentionpolicies_test.go
+++ b/test/e2e/customconfigs/objectretentionpolicies_test.go
@@ -30,7 +30,7 @@ import (
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
 	"sigs.k8s.io/kueue/pkg/features"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
 	"sigs.k8s.io/kueue/test/util"
@@ -86,6 +86,7 @@ var _ = ginkgo.Describe("ObjectRetentionPolicies", ginkgo.Ordered, ginkgo.Contin
 
 		job := testingjob.MakeJob("job", ns.Name).
 			Queue(kueue.LocalQueueName(lq.Name)).
+			Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 			RequestAndLimit(corev1.ResourceCPU, "1").
 			Obj()
 		ginkgo.By("Creating a Job", func() {
@@ -120,13 +121,13 @@ var _ = ginkgo.Describe("ObjectRetentionPolicies", ginkgo.Ordered, ginkgo.Contin
 		ginkgo.By("Checking that the Job is deleted", func() {
 			createdJob := &batchv1.Job{}
 			gomega.Eventually(func(g gomega.Gomega) {
-				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(job), createdJob)).To(testing.BeNotFoundError())
+				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(job), createdJob)).To(utiltesting.BeNotFoundError())
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 
 		ginkgo.By("Checking that the Workload is deleted", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
-				g.Expect(k8sClient.Get(ctx, wlKey, wl)).To(testing.BeNotFoundError())
+				g.Expect(k8sClient.Get(ctx, wlKey, wl)).To(utiltesting.BeNotFoundError())
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 	})
@@ -202,7 +203,7 @@ var _ = ginkgo.Describe("ObjectRetentionPolicies with TinyTimeout", ginkgo.Order
 
 			ginkgo.By("Checking that the Workload is deleted after it is finished", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, wl)).To(testing.BeNotFoundError())
+					g.Expect(k8sClient.Get(ctx, wlKey, wl)).To(utiltesting.BeNotFoundError())
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -318,6 +319,7 @@ var _ = ginkgo.Describe("ObjectRetentionPolicies with TinyTimeout and RequeuingL
 	ginkgo.It("should delete Job", func() {
 		job := testingjob.MakeJob("job", ns.Name).
 			Queue(kueue.LocalQueueName(lq.Name)).
+			Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 			RequestAndLimit(corev1.ResourceCPU, "1").
 			Obj()
 		ginkgo.By("Creating a Job", func() {
@@ -335,7 +337,7 @@ var _ = ginkgo.Describe("ObjectRetentionPolicies with TinyTimeout and RequeuingL
 			}
 			wl := &kueue.Workload{}
 			gomega.Eventually(func(g gomega.Gomega) {
-				g.Expect(k8sClient.Get(ctx, wlKey, wl)).To(testing.BeNotFoundError())
+				g.Expect(k8sClient.Get(ctx, wlKey, wl)).To(utiltesting.BeNotFoundError())
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 	})
diff --git a/test/e2e/customconfigs/podintegrationautoenablement_test.go b/test/e2e/customconfigs/podintegrationautoenablement_test.go
index a4b15b88f..fbae082e2 100644
--- a/test/e2e/customconfigs/podintegrationautoenablement_test.go
+++ b/test/e2e/customconfigs/podintegrationautoenablement_test.go
@@ -28,7 +28,7 @@ import (
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobs/statefulset"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingpod "sigs.k8s.io/kueue/pkg/util/testingjobs/pod"
 	testingsts "sigs.k8s.io/kueue/pkg/util/testingjobs/statefulset"
@@ -93,7 +93,7 @@ var _ = ginkgo.Describe("Auto-Enablement of Pod Integration for Pod-Dependent Fr
 			createdWorkload := &kueue.Workload{}
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				g.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+				g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
 
diff --git a/test/e2e/customconfigs/waitforpodsready_test.go b/test/e2e/customconfigs/waitforpodsready_test.go
index 863d1796c..3646286b0 100644
--- a/test/e2e/customconfigs/waitforpodsready_test.go
+++ b/test/e2e/customconfigs/waitforpodsready_test.go
@@ -30,7 +30,7 @@ import (
 	configapi "sigs.k8s.io/kueue/apis/config/v1beta2"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
 	testingjobspod "sigs.k8s.io/kueue/pkg/util/testingjobs/pod"
@@ -135,6 +135,7 @@ var _ = ginkgo.Describe("WaitForPodsReady with tiny Timeout and no RecoveryTimeo
 		ginkgo.By("creating a suspended job so its pods never report Ready", func() {
 			job = testingjob.MakeJob("job-timeout", ns.Name).
 				Queue(kueue.LocalQueueName(lq.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				Request(corev1.ResourceCPU, "2").
 				Parallelism(1).
 				Obj()
@@ -156,8 +157,8 @@ var _ = ginkgo.Describe("WaitForPodsReady with tiny Timeout and no RecoveryTimeo
 		ginkgo.By("waiting for the workload to be evicted", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, wlKey, &wl)).Should(gomega.Succeed())
-				g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusFalseAndReason(kueue.WorkloadPodsReady, kueue.WorkloadWaitForStart))
-				g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason(kueue.WorkloadEvicted, kueue.WorkloadEvictedByPodsReadyTimeout))
+				g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusFalseAndReason(kueue.WorkloadPodsReady, kueue.WorkloadWaitForStart))
+				g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason(kueue.WorkloadEvicted, kueue.WorkloadEvictedByPodsReadyTimeout))
 				g.Expect(wl.Status.SchedulingStats.Evictions).To(
 					gomega.BeComparableTo([]kueue.WorkloadSchedulingStatsEviction{{
 						Reason:          kueue.WorkloadEvictedByPodsReadyTimeout,
@@ -308,7 +309,7 @@ var _ = ginkgo.Describe("WaitForPodsReady with default Timeout and a tiny Recove
 		ginkgo.By("checking workload availability", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, wlKey, &wl)).Should(gomega.Succeed())
-				g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadPodsReady))
+				g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadPodsReady))
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 
@@ -321,9 +322,9 @@ var _ = ginkgo.Describe("WaitForPodsReady with default Timeout and a tiny Recove
 				g.Expect(k8sClient.Get(ctx, wlKey, &wl)).Should(gomega.Succeed())
 				g.Expect(wl.Status.RequeueState).ShouldNot(gomega.BeNil())
 				g.Expect(*wl.Status.RequeueState.Count).To(gomega.Equal(int32(1)))
-				g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason(kueue.WorkloadPodsReady, kueue.WorkloadStarted))
-				g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusFalse(kueue.WorkloadEvicted))
-				g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadRequeued))
+				g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason(kueue.WorkloadPodsReady, kueue.WorkloadStarted))
+				g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusFalse(kueue.WorkloadEvicted))
+				g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadRequeued))
 
 				g.Expect(wl.Status.SchedulingStats.Evictions).To(
 					gomega.BeComparableTo([]kueue.WorkloadSchedulingStatsEviction{{
@@ -453,7 +454,7 @@ var _ = ginkgo.Describe("WaitForPodsReady with default Timeout and a long Recove
 		ginkgo.By("checking workload availability", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, wlKey, &wl)).Should(gomega.Succeed())
-				g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadPodsReady))
+				g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadPodsReady))
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 
@@ -472,7 +473,7 @@ var _ = ginkgo.Describe("WaitForPodsReady with default Timeout and a long Recove
 		ginkgo.By("verifying the pod is recovered before recoveryTimeout", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, wlKey, &wl)).Should(gomega.Succeed())
-				g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason(kueue.WorkloadPodsReady, kueue.WorkloadRecovered))
+				g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason(kueue.WorkloadPodsReady, kueue.WorkloadRecovered))
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 
diff --git a/test/e2e/kueueviz/package-lock.json b/test/e2e/kueueviz/package-lock.json
index 83e752042..b693bb1d1 100644
--- a/test/e2e/kueueviz/package-lock.json
+++ b/test/e2e/kueueviz/package-lock.json
@@ -9,7 +9,7 @@
       "version": "0.14.4",
       "devDependencies": {
         "@testing-library/cypress": "^10.1.0",
-        "cypress": "^15.5.0",
+        "cypress": "^15.6.0",
         "depcheck": "^1.4.7"
       }
     },
@@ -1015,9 +1015,9 @@
       }
     },
     "node_modules/cypress": {
-      "version": "15.5.0",
-      "resolved": "https://registry.npmjs.org/cypress/-/cypress-15.5.0.tgz",
-      "integrity": "sha512-7jXBsh5hTfjxr9QQONC2IbdTj0nxSyU8x4eiarMZBzXzCj3pedKviUx8JnLcE4vL8e0TsOzp70WSLRORjEssRA==",
+      "version": "15.6.0",
+      "resolved": "https://registry.npmjs.org/cypress/-/cypress-15.6.0.tgz",
+      "integrity": "sha512-Vqo66GG1vpxZ7H1oDX9umfmzA3nF7Wy80QAc3VjwPREO5zTY4d1xfQFNPpOWleQl9vpdmR2z1liliOcYlRX6rQ==",
       "dev": true,
       "hasInstallScript": true,
       "license": "MIT",
diff --git a/test/e2e/kueueviz/package.json b/test/e2e/kueueviz/package.json
index 22106b649..8a50d2e93 100644
--- a/test/e2e/kueueviz/package.json
+++ b/test/e2e/kueueviz/package.json
@@ -7,7 +7,7 @@
   },
   "devDependencies": {
     "@testing-library/cypress": "^10.1.0",
-    "cypress": "^15.5.0",
+    "cypress": "^15.6.0",
     "depcheck": "^1.4.7"
   }
 }
diff --git a/test/e2e/multikueue/tas_test.go b/test/e2e/multikueue/tas_test.go
new file mode 100644
index 000000000..938e528d7
--- /dev/null
+++ b/test/e2e/multikueue/tas_test.go
@@ -0,0 +1,384 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package mke2e
+
+import (
+	"context"
+	"fmt"
+
+	"github.com/google/go-cmp/cmp/cmpopts"
+	"github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
+	batchv1 "k8s.io/api/batch/v1"
+	corev1 "k8s.io/api/core/v1"
+	apimeta "k8s.io/apimachinery/pkg/api/meta"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/utils/ptr"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
+	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
+	"sigs.k8s.io/kueue/pkg/util/admissioncheck"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
+	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
+	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
+	"sigs.k8s.io/kueue/pkg/workload"
+	"sigs.k8s.io/kueue/test/util"
+)
+
+const (
+	tasNodeGroupLabel = "cloud.provider.com/node-group"
+	instanceType      = "tas-node"
+)
+
+var _ = ginkgo.Describe("MultiKueue with TopologyAwareScheduling", func() {
+	var (
+		managerNs *corev1.Namespace
+		worker1Ns *corev1.Namespace
+		worker2Ns *corev1.Namespace
+
+		workerCluster1   *kueue.MultiKueueCluster
+		workerCluster2   *kueue.MultiKueueCluster
+		multiKueueConfig *kueue.MultiKueueConfig
+		multiKueueAc     *kueue.AdmissionCheck
+
+		managerTopology *kueue.Topology
+		managerFlavor   *kueue.ResourceFlavor
+		managerCq       *kueue.ClusterQueue
+		managerLq       *kueue.LocalQueue
+
+		worker1Topology *kueue.Topology
+		worker1Flavor   *kueue.ResourceFlavor
+		worker1Cq       *kueue.ClusterQueue
+		worker1Lq       *kueue.LocalQueue
+
+		worker2Topology *kueue.Topology
+		worker2Flavor   *kueue.ResourceFlavor
+		worker2Cq       *kueue.ClusterQueue
+		worker2Lq       *kueue.LocalQueue
+	)
+
+	ginkgo.BeforeEach(func() {
+		managerNs = util.CreateNamespaceFromPrefixWithLog(ctx, k8sManagerClient, "multikueue-tas-")
+		worker1Ns = util.CreateNamespaceWithLog(ctx, k8sWorker1Client, managerNs.Name)
+		worker2Ns = util.CreateNamespaceWithLog(ctx, k8sWorker2Client, managerNs.Name)
+
+		workerCluster1 = utiltestingapi.MakeMultiKueueCluster("worker1").KubeConfig(kueue.SecretLocationType, "multikueue1").Obj()
+		util.MustCreate(ctx, k8sManagerClient, workerCluster1)
+
+		workerCluster2 = utiltestingapi.MakeMultiKueueCluster("worker2").KubeConfig(kueue.SecretLocationType, "multikueue2").Obj()
+		util.MustCreate(ctx, k8sManagerClient, workerCluster2)
+
+		multiKueueConfig = utiltestingapi.MakeMultiKueueConfig("multikueueconfig").Clusters("worker1", "worker2").Obj()
+		util.MustCreate(ctx, k8sManagerClient, multiKueueConfig)
+
+		multiKueueAc = utiltestingapi.MakeAdmissionCheck("ac1").
+			ControllerName(kueue.MultiKueueControllerName).
+			Parameters(kueue.GroupVersion.Group, "MultiKueueConfig", multiKueueConfig.Name).
+			Obj()
+		util.MustCreate(ctx, k8sManagerClient, multiKueueAc)
+
+		ginkgo.By("wait for check active", func() {
+			updatedAc := kueue.AdmissionCheck{}
+			acKey := client.ObjectKeyFromObject(multiKueueAc)
+			gomega.Eventually(func(g gomega.Gomega) {
+				g.Expect(k8sManagerClient.Get(ctx, acKey, &updatedAc)).To(gomega.Succeed())
+				g.Expect(updatedAc.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.AdmissionCheckActive))
+			}, util.Timeout, util.Interval).Should(gomega.Succeed())
+		})
+
+		managerTopology = utiltestingapi.MakeTopology("default").Levels(corev1.LabelHostname).Obj()
+		util.MustCreate(ctx, k8sManagerClient, managerTopology)
+
+		managerFlavor = utiltestingapi.MakeResourceFlavor("tas-flavor").
+			NodeLabel(tasNodeGroupLabel, instanceType).
+			TopologyName(managerTopology.Name).
+			Obj()
+		util.MustCreate(ctx, k8sManagerClient, managerFlavor)
+
+		managerCq = utiltestingapi.MakeClusterQueue("q1").
+			ResourceGroup(
+				*utiltestingapi.MakeFlavorQuotas(managerFlavor.Name).
+					Resource(corev1.ResourceCPU, "8").
+					Resource(corev1.ResourceMemory, "8Gi").
+					Obj(),
+			).
+			AdmissionChecks(kueue.AdmissionCheckReference(multiKueueAc.Name)).
+			Obj()
+		util.MustCreate(ctx, k8sManagerClient, managerCq)
+
+		managerLq = utiltestingapi.MakeLocalQueue(managerCq.Name, managerNs.Name).ClusterQueue(managerCq.Name).Obj()
+		util.MustCreate(ctx, k8sManagerClient, managerLq)
+
+		worker1Topology = utiltestingapi.MakeTopology("default").Levels(corev1.LabelHostname).Obj()
+		util.MustCreate(ctx, k8sWorker1Client, worker1Topology)
+
+		worker1Flavor = utiltestingapi.MakeResourceFlavor("tas-flavor").
+			NodeLabel(tasNodeGroupLabel, instanceType).
+			TopologyName(worker1Topology.Name).
+			Obj()
+		util.MustCreate(ctx, k8sWorker1Client, worker1Flavor)
+
+		worker1Cq = utiltestingapi.MakeClusterQueue("q1").
+			ResourceGroup(
+				*utiltestingapi.MakeFlavorQuotas(worker1Flavor.Name).
+					Resource(corev1.ResourceCPU, "8").
+					Resource(corev1.ResourceMemory, "4Gi").
+					Obj(),
+			).
+			Obj()
+		util.MustCreate(ctx, k8sWorker1Client, worker1Cq)
+
+		worker1Lq = utiltestingapi.MakeLocalQueue(worker1Cq.Name, worker1Ns.Name).ClusterQueue(worker1Cq.Name).Obj()
+		util.MustCreate(ctx, k8sWorker1Client, worker1Lq)
+
+		worker2Topology = utiltestingapi.MakeTopology("default").Levels(corev1.LabelHostname).Obj()
+		util.MustCreate(ctx, k8sWorker2Client, worker2Topology)
+
+		worker2Flavor = utiltestingapi.MakeResourceFlavor("tas-flavor").
+			NodeLabel(tasNodeGroupLabel, instanceType).
+			TopologyName(worker2Topology.Name).
+			Obj()
+		util.MustCreate(ctx, k8sWorker2Client, worker2Flavor)
+
+		worker2Cq = utiltestingapi.MakeClusterQueue("q1").
+			ResourceGroup(
+				*utiltestingapi.MakeFlavorQuotas(worker2Flavor.Name).
+					Resource(corev1.ResourceCPU, "4").
+					Resource(corev1.ResourceMemory, "8Gi").
+					Obj(),
+			).
+			Obj()
+		util.MustCreate(ctx, k8sWorker2Client, worker2Cq)
+
+		worker2Lq = utiltestingapi.MakeLocalQueue(worker2Cq.Name, worker2Ns.Name).ClusterQueue(worker2Cq.Name).Obj()
+		util.MustCreate(ctx, k8sWorker2Client, worker2Lq)
+	})
+
+	ginkgo.AfterEach(func() {
+		gomega.Expect(util.DeleteNamespace(ctx, k8sManagerClient, managerNs)).To(gomega.Succeed())
+		gomega.Expect(util.DeleteNamespace(ctx, k8sWorker1Client, worker1Ns)).To(gomega.Succeed())
+		gomega.Expect(util.DeleteNamespace(ctx, k8sWorker2Client, worker2Ns)).To(gomega.Succeed())
+
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sWorker1Client, worker1Cq, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sWorker1Client, worker1Flavor, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sWorker1Client, worker1Topology, true, util.LongTimeout)
+
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sWorker2Client, worker2Cq, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sWorker2Client, worker2Flavor, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sWorker2Client, worker2Topology, true, util.LongTimeout)
+
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sManagerClient, managerCq, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sManagerClient, managerFlavor, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sManagerClient, managerTopology, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sManagerClient, multiKueueAc, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sManagerClient, multiKueueConfig, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sManagerClient, workerCluster1, true, util.LongTimeout)
+		util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sManagerClient, workerCluster2, true, util.LongTimeout)
+
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sManagerClient, managerNs)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sWorker1Client, worker1Ns)
+		util.ExpectAllPodsInNamespaceDeleted(ctx, k8sWorker2Client, worker2Ns)
+	})
+
+	ginkgo.When("Creating a Job with TAS requirements", func() {
+		ginkgo.It("Should admit a Job and assign topology in the worker cluster", func() {
+			job := testingjob.MakeJob("tas-job", managerNs.Name).
+				Queue(kueue.LocalQueueName(managerLq.Name)).
+				Parallelism(2).
+				Completions(2).
+				RequestAndLimit(corev1.ResourceCPU, "500m").
+				RequestAndLimit(corev1.ResourceMemory, "200Mi").
+				TerminationGracePeriod(1).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
+				Obj()
+			job = (&testingjob.JobWrapper{Job: *job}).
+				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, corev1.LabelHostname).
+				Obj()
+
+			ginkgo.By("Creating the job", func() {
+				util.MustCreate(ctx, k8sManagerClient, job)
+				gomega.Eventually(func(g gomega.Gomega) {
+					createdJob := &batchv1.Job{}
+					g.Expect(k8sManagerClient.Get(ctx, client.ObjectKeyFromObject(job), createdJob)).To(gomega.Succeed())
+					g.Expect(ptr.Deref(createdJob.Spec.ManagedBy, "")).To(gomega.BeEquivalentTo(kueue.MultiKueueControllerName))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			createdWorkload := &kueue.Workload{}
+			wlLookupKey := types.NamespacedName{Name: workloadjob.GetWorkloadNameForJob(job.Name, job.UID), Namespace: managerNs.Name}
+
+			var assignedWorkerCluster client.Client
+			var assignedWorkerCtx context.Context
+			var assignedClusterName string
+			ginkgo.By("checking which worker cluster was assigned", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					managerWl := &kueue.Workload{}
+					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
+					g.Expect(managerWl.Status.ClusterName).NotTo(gomega.BeNil())
+
+					assignedClusterName = *managerWl.Status.ClusterName
+					g.Expect(assignedClusterName).To(gomega.Or(gomega.Equal(workerCluster1.Name), gomega.Equal(workerCluster2.Name)))
+					if assignedClusterName == workerCluster1.Name {
+						assignedWorkerCluster = k8sWorker1Client
+						assignedWorkerCtx = ctx
+					} else {
+						assignedWorkerCluster = k8sWorker2Client
+						assignedWorkerCtx = ctx
+					}
+
+					g.Expect(admissioncheck.FindAdmissionCheck(managerWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAc.Name))).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
+						Name:    kueue.AdmissionCheckReference(multiKueueAc.Name),
+						State:   kueue.CheckStateReady,
+						Message: fmt.Sprintf(`The workload got reservation on "%s"`, assignedClusterName),
+					}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime")))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By(fmt.Sprintf("Waiting for TopologyAssignment to be computed in %s", assignedClusterName), func() {
+				workerWlLookupKey := types.NamespacedName{Name: wlLookupKey.Name, Namespace: managerNs.Name}
+				workerWl := &kueue.Workload{}
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(assignedWorkerCluster.Get(assignedWorkerCtx, workerWlLookupKey, workerWl)).To(gomega.Succeed())
+					g.Expect(workerWl.Status.Admission).NotTo(gomega.BeNil())
+					g.Expect(workerWl.Status.Admission.PodSetAssignments).To(gomega.HaveLen(1))
+					g.Expect(workerWl.Status.Admission.PodSetAssignments[0].TopologyAssignment).NotTo(gomega.BeNil())
+					g.Expect(workerWl.Status.Admission.PodSetAssignments[0].TopologyAssignment.Levels).To(gomega.Equal([]string{corev1.LabelHostname}))
+					g.Expect(workerWl.Status.Admission.PodSetAssignments[0].TopologyAssignment.Domains).NotTo(gomega.BeEmpty())
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for DelayedTopologyRequest to be marked Ready on manager", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					managerWl := &kueue.Workload{}
+					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
+					g.Expect(managerWl.Status.Admission).NotTo(gomega.BeNil())
+					g.Expect(managerWl.Status.Admission.PodSetAssignments).To(gomega.HaveLen(1))
+					g.Expect(managerWl.Status.Admission.PodSetAssignments[0].DelayedTopologyRequest).To(gomega.Equal(ptr.To(kueue.DelayedTopologyRequestStateReady)))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for the job to get status updates", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					createdJob := batchv1.Job{}
+					g.Expect(k8sManagerClient.Get(ctx, client.ObjectKeyFromObject(job), &createdJob)).To(gomega.Succeed())
+					g.Expect(createdJob.Status.StartTime).NotTo(gomega.BeNil())
+					g.Expect(createdJob.Status.Active).To(gomega.Equal(int32(2)))
+					g.Expect(createdJob.Status.CompletionTime).To(gomega.BeNil())
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Finishing the job's pods", func() {
+				listOpts := util.GetListOptsFromLabel(fmt.Sprintf("batch.kubernetes.io/job-name=%s", job.Name))
+				if assignedClusterName == workerCluster1.Name {
+					util.WaitForActivePodsAndTerminate(ctx, k8sWorker1Client, worker1RestClient, worker1Cfg, job.Namespace, 2, 0, listOpts)
+				} else {
+					util.WaitForActivePodsAndTerminate(ctx, k8sWorker2Client, worker2RestClient, worker2Cfg, job.Namespace, 2, 0, listOpts)
+				}
+			})
+
+			ginkgo.By("Waiting for the job to finish", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason(kueue.WorkloadFinished, kueue.WorkloadFinishedReasonSucceeded))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Checking no objects are left in the worker clusters and the job is completed", func() {
+				expectObjectToBeDeletedOnWorkerClusters(ctx, createdWorkload)
+				expectObjectToBeDeletedOnWorkerClusters(ctx, job)
+
+				createdJob := &batchv1.Job{}
+				gomega.Expect(k8sManagerClient.Get(ctx, client.ObjectKeyFromObject(job), createdJob)).To(gomega.Succeed())
+				gomega.Expect(createdJob.Status.Conditions).To(gomega.ContainElement(gomega.BeComparableTo(
+					batchv1.JobCondition{
+						Type:   batchv1.JobComplete,
+						Status: corev1.ConditionTrue,
+					},
+					cmpopts.IgnoreFields(batchv1.JobCondition{}, "LastTransitionTime", "LastProbeTime", "Reason", "Message"))))
+			})
+		})
+
+		ginkgo.It("Should handle implicit TAS", func() {
+			job := testingjob.MakeJob("implicit-tas-job", managerNs.Name).
+				Queue(kueue.LocalQueueName(managerLq.Name)).
+				Parallelism(2).
+				Completions(2).
+				RequestAndLimit(corev1.ResourceCPU, "500m").
+				RequestAndLimit(corev1.ResourceMemory, "200Mi").
+				TerminationGracePeriod(1).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
+				Obj()
+
+			ginkgo.By("Creating the job without TAS annotation", func() {
+				util.MustCreate(ctx, k8sManagerClient, job)
+				gomega.Eventually(func(g gomega.Gomega) {
+					createdJob := &batchv1.Job{}
+					g.Expect(k8sManagerClient.Get(ctx, client.ObjectKeyFromObject(job), createdJob)).To(gomega.Succeed())
+					g.Expect(ptr.Deref(createdJob.Spec.ManagedBy, "")).To(gomega.BeEquivalentTo(kueue.MultiKueueControllerName))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			createdWorkload := &kueue.Workload{}
+			wlLookupKey := types.NamespacedName{Name: workloadjob.GetWorkloadNameForJob(job.Name, job.UID), Namespace: managerNs.Name}
+
+			var assignedClusterName string
+			ginkgo.By("checking which worker cluster was assigned", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					managerWl := &kueue.Workload{}
+					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
+					g.Expect(managerWl.Status.ClusterName).NotTo(gomega.BeNil())
+					assignedClusterName = *managerWl.Status.ClusterName
+					g.Expect(apimeta.FindStatusCondition(managerWl.Status.Conditions, kueue.WorkloadAdmitted)).To(gomega.BeComparableTo(&metav1.Condition{
+						Type:    kueue.WorkloadAdmitted,
+						Status:  metav1.ConditionTrue,
+						Reason:  "Admitted",
+						Message: "The workload is admitted",
+					}, util.IgnoreConditionTimestampsAndObservedGeneration))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for DelayedTopologyRequest to be marked Ready on manager", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					managerWl := &kueue.Workload{}
+					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
+					g.Expect(managerWl.Status.Admission).NotTo(gomega.BeNil())
+					g.Expect(managerWl.Status.Admission.PodSetAssignments).To(gomega.HaveLen(1))
+					g.Expect(managerWl.Status.Admission.PodSetAssignments[0].DelayedTopologyRequest).To(gomega.Equal(ptr.To(kueue.DelayedTopologyRequestStateReady)))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Finishing the job", func() {
+				listOpts := util.GetListOptsFromLabel(fmt.Sprintf("batch.kubernetes.io/job-name=%s", job.Name))
+				if assignedClusterName == workerCluster1.Name {
+					util.WaitForActivePodsAndTerminate(ctx, k8sWorker1Client, worker1RestClient, worker1Cfg, job.Namespace, 2, 0, listOpts)
+				} else {
+					util.WaitForActivePodsAndTerminate(ctx, k8sWorker2Client, worker2RestClient, worker2Cfg, job.Namespace, 2, 0, listOpts)
+				}
+			})
+
+			ginkgo.By("Waiting for the job to finish", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
+					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason(kueue.WorkloadFinished, kueue.WorkloadFinishedReasonSucceeded))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
+})
diff --git a/test/e2e/singlecluster/appwrapper_test.go b/test/e2e/singlecluster/appwrapper_test.go
index 90d56da15..528355fb2 100644
--- a/test/e2e/singlecluster/appwrapper_test.go
+++ b/test/e2e/singlecluster/appwrapper_test.go
@@ -27,7 +27,7 @@ import (
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	"sigs.k8s.io/kueue/pkg/controller/jobs/appwrapper"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	awtesting "sigs.k8s.io/kueue/pkg/util/testingjobs/appwrapper"
 	testingdeploy "sigs.k8s.io/kueue/pkg/util/testingjobs/deployment"
@@ -158,7 +158,7 @@ var _ = ginkgo.Describe("AppWrapper", func() {
 				g.Expect(k8sClient.List(ctx, createdWorkloads, client.InNamespace(aw.Namespace))).To(gomega.Succeed())
 				g.Expect(createdWorkloads.Items).To(gomega.HaveLen(1))
 				g.Expect(createdWorkloads.Items[0].Name).To(gomega.Equal(appwrapper.GetWorkloadNameForAppWrapper(aw.Name, aw.UID)))
-				g.Expect(createdWorkloads.Items[0].Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+				g.Expect(createdWorkloads.Items[0].Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 
diff --git a/test/e2e/singlecluster/deployment_test.go b/test/e2e/singlecluster/deployment_test.go
index f39a408e3..10073b937 100644
--- a/test/e2e/singlecluster/deployment_test.go
+++ b/test/e2e/singlecluster/deployment_test.go
@@ -27,7 +27,7 @@ import (
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	"sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobs/pod"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	deploymenttesting "sigs.k8s.io/kueue/pkg/util/testingjobs/deployment"
 	"sigs.k8s.io/kueue/test/util"
@@ -111,7 +111,7 @@ var _ = ginkgo.Describe("Deployment", func() {
 					Namespace: p.Namespace,
 				}
 				gomega.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				gomega.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+				gomega.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				createdWorkloads = append(createdWorkloads, createdWorkload)
 			}
 		})
@@ -161,7 +161,7 @@ var _ = ginkgo.Describe("Deployment", func() {
 				g.Expect(k8sClient.List(ctx, createdWorkloads, client.InNamespace(ns.Name))).To(gomega.Succeed())
 				g.Expect(createdWorkloads.Items).To(gomega.HaveLen(3))
 				for _, wl := range createdWorkloads.Items {
-					g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusFalse(kueue.WorkloadQuotaReserved))
+					g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusFalse(kueue.WorkloadQuotaReserved))
 				}
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
@@ -202,7 +202,7 @@ var _ = ginkgo.Describe("Deployment", func() {
 				g.Expect(k8sClient.List(ctx, createdWorkloads, client.InNamespace(ns.Name))).To(gomega.Succeed())
 				g.Expect(createdWorkloads.Items).To(gomega.HaveLen(3))
 				for _, wl := range createdWorkloads.Items {
-					g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(wl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
diff --git a/test/e2e/singlecluster/e2e_test.go b/test/e2e/singlecluster/e2e_test.go
index c673cb2e5..961753d8b 100644
--- a/test/e2e/singlecluster/e2e_test.go
+++ b/test/e2e/singlecluster/e2e_test.go
@@ -34,7 +34,7 @@ import (
 	"sigs.k8s.io/kueue/pkg/controller/jobframework"
 	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
 	"sigs.k8s.io/kueue/pkg/util/slices"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
 	"sigs.k8s.io/kueue/pkg/workload"
@@ -50,6 +50,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 		ns = util.CreateNamespaceFromPrefixWithLog(ctx, k8sClient, "e2e-")
 		sampleJob = testingjob.MakeJob("test-job", ns.Name).
 			Queue("main").
+			Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 			RequestAndLimit(corev1.ResourceCPU, "1").
 			RequestAndLimit(corev1.ResourceMemory, "20Mi").
 			Obj()
@@ -215,7 +216,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 				g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-				g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+				g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 
@@ -277,7 +278,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), createdWorkload)).To(gomega.Succeed())
 					g.Expect(createdWorkload.Finalizers).NotTo(gomega.ContainElement(kueue.ResourceInUseFinalizerName))
-					g.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason(kueue.WorkloadFinished, kueue.WorkloadFinishedReasonFailed))
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason(kueue.WorkloadFinished, kueue.WorkloadFinishedReasonFailed))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -285,7 +286,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 		ginkgo.It("Should readmit preempted job with priorityClass into a separate flavor", func() {
 			util.MustCreate(ctx, k8sClient, sampleJob)
 
-			highPriorityClass := testing.MakePriorityClass("high").PriorityValue(100).Obj()
+			highPriorityClass := utiltesting.MakePriorityClass("high").PriorityValue(100).Obj()
 			util.MustCreate(ctx, k8sClient, highPriorityClass)
 			ginkgo.DeferCleanup(func() {
 				gomega.Expect(k8sClient.Delete(ctx, highPriorityClass)).To(gomega.Succeed())
@@ -300,6 +301,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 			ginkgo.By("Job is preempted by higher priority job", func() {
 				job := testingjob.MakeJob("high", ns.Name).
 					Queue("main").
+					Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 					PriorityClass("high").
 					RequestAndLimit(corev1.ResourceCPU, "1").
 					NodeSelector("instance-type", "on-demand"). // target the same flavor to cause preemption
@@ -336,6 +338,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 			ginkgo.By("Job is preempted by higher priority job", func() {
 				job := testingjob.MakeJob("high-with-wpc", ns.Name).
 					Queue("main").
+					Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 					WorkloadPriorityClass("high-workload").
 					RequestAndLimit(corev1.ResourceCPU, "1").
 					NodeSelector("instance-type", "on-demand"). // target the same flavor to cause preemption
@@ -386,7 +389,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -434,7 +437,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, jobKey, createdJob)).Should(gomega.Succeed())
 					createdJob.Labels[constants.WorkloadPriorityClassLabel] = ""
-					g.Expect(k8sClient.Update(ctx, createdJob)).Should(testing.BeForbiddenError())
+					g.Expect(k8sClient.Update(ctx, createdJob)).Should(utiltesting.BeForbiddenError())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -497,7 +500,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 		})
 
 		ginkgo.It("Should deduplicate env variables", func() {
-			highPriorityClass := testing.MakePriorityClass("high").PriorityValue(100).Obj()
+			highPriorityClass := utiltesting.MakePriorityClass("high").PriorityValue(100).Obj()
 			util.MustCreate(ctx, k8sClient, highPriorityClass)
 			ginkgo.DeferCleanup(func() {
 				gomega.Expect(k8sClient.Delete(ctx, highPriorityClass)).To(gomega.Succeed())
@@ -505,10 +508,11 @@ var _ = ginkgo.Describe("Kueue", func() {
 
 			lowJob := testingjob.MakeJob("low", ns.Name).
 				Queue(kueue.LocalQueueName(localQueue.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				Parallelism(1).
 				NodeSelector("instance-type", "on-demand").
 				Containers(
-					*testing.MakeContainer().
+					*utiltesting.MakeContainer().
 						Name("c").
 						Image("sleep").
 						WithResourceReq(corev1.ResourceCPU, "1").
@@ -539,6 +543,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 
 			highJob := testingjob.MakeJob("high", ns.Name).
 				Queue(kueue.LocalQueueName(localQueue.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				Parallelism(1).
 				PriorityClass(highPriorityClass.Name).
 				Request(corev1.ResourceCPU, "1").
@@ -563,7 +568,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, lowWlLookupKey, lowCreatedWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.IsEvicted(lowCreatedWorkload)).Should(gomega.BeTrue())
-					g.Expect(lowCreatedWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadPreempted))
+					g.Expect(lowCreatedWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadPreempted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -642,7 +647,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, jobKey, createdJob)).Should(gomega.Succeed())
 					createdJob.Labels[constants.WorkloadPriorityClassLabel] = ""
-					g.Expect(k8sClient.Update(ctx, createdJob)).Should(testing.BeForbiddenError())
+					g.Expect(k8sClient.Update(ctx, createdJob)).Should(utiltesting.BeForbiddenError())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -706,7 +711,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 			ginkgo.By("waiting for the workload to be assigned", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadQuotaReserved))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadQuotaReserved))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -726,7 +731,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 					workload.SetAdmissionCheckState(&patch.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:  "check1",
 						State: kueue.CheckStateReady,
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Patch(ctx, patch, client.Apply, client.FieldOwner("test-admission-check-controller"), client.ForceOwnership)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -738,7 +743,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 				g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-				g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+				g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 
@@ -764,7 +769,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 					workload.SetAdmissionCheckState(&patch.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:  "check1",
 						State: kueue.CheckStateReady,
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Patch(ctx, patch, client.Apply, client.FieldOwner("test-admission-check-controller"), client.ForceOwnership)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -780,7 +785,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 					workload.SetAdmissionCheckState(&patch.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:  "check1",
 						State: kueue.CheckStateRejected,
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Patch(ctx, patch, client.Apply,
 						client.FieldOwner("test-admission-check-controller"),
 						client.ForceOwnership)).Should(gomega.Succeed())
diff --git a/test/e2e/singlecluster/e2e_v1beta1_test.go b/test/e2e/singlecluster/e2e_v1beta1_test.go
index 25437afae..20d8dbfa8 100644
--- a/test/e2e/singlecluster/e2e_v1beta1_test.go
+++ b/test/e2e/singlecluster/e2e_v1beta1_test.go
@@ -27,7 +27,7 @@ import (
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta1"
 	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
 	"sigs.k8s.io/kueue/test/util"
@@ -42,6 +42,7 @@ var _ = ginkgo.Describe("Kueue v1beta2", func() {
 		ns = util.CreateNamespaceFromPrefixWithLog(ctx, k8sClient, "e2e-")
 		sampleJob = testingjob.MakeJob("test-job", ns.Name).
 			Queue("main").
+			Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 			RequestAndLimit(corev1.ResourceCPU, "1").
 			RequestAndLimit(corev1.ResourceMemory, "20Mi").
 			Obj()
@@ -131,7 +132,7 @@ var _ = ginkgo.Describe("Kueue v1beta2", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 				g.Expect(hasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-				g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+				g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 			}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 		})
 	})
diff --git a/test/e2e/singlecluster/jobset_test.go b/test/e2e/singlecluster/jobset_test.go
index 058839d43..e515a98ae 100644
--- a/test/e2e/singlecluster/jobset_test.go
+++ b/test/e2e/singlecluster/jobset_test.go
@@ -26,7 +26,7 @@ import (
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	workloadjobset "sigs.k8s.io/kueue/pkg/controller/jobs/jobset"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjobset "sigs.k8s.io/kueue/pkg/util/testingjobs/jobset"
 	"sigs.k8s.io/kueue/test/util"
@@ -97,7 +97,7 @@ var _ = ginkgo.Describe("JobSet", func() {
 			ginkgo.By("Waiting for the jobSet to finish", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdLeaderWorkload)).To(gomega.Succeed())
-					g.Expect(createdLeaderWorkload.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason(kueue.WorkloadFinished, kueue.WorkloadFinishedReasonSucceeded))
+					g.Expect(createdLeaderWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason(kueue.WorkloadFinished, kueue.WorkloadFinishedReasonSucceeded))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
diff --git a/test/e2e/singlecluster/leaderworkerset_test.go b/test/e2e/singlecluster/leaderworkerset_test.go
index d740860d1..58fd06a39 100644
--- a/test/e2e/singlecluster/leaderworkerset_test.go
+++ b/test/e2e/singlecluster/leaderworkerset_test.go
@@ -31,7 +31,7 @@ import (
 	ctrlconstants "sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobs/leaderworkerset"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	leaderworkersettesting "sigs.k8s.io/kueue/pkg/util/testingjobs/leaderworkerset"
 	"sigs.k8s.io/kueue/test/util"
@@ -101,7 +101,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -152,7 +152,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -201,7 +201,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(2)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -259,7 +259,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 						g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 
@@ -281,7 +281,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 						g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(2)))
-						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 
@@ -340,7 +340,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 						g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(2)))
-						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 
@@ -368,7 +368,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 						g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 
@@ -424,7 +424,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 						g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 
@@ -454,7 +454,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 						g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 
@@ -466,7 +466,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				wlLookupKey2 := types.NamespacedName{Name: leaderworkerset.GetWorkloadName(lws.UID, lws.Name, "1"), Namespace: ns.Name}
 				ginkgo.By("Check workload for group 2 is deleted", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
-						g.Expect(k8sClient.Get(ctx, wlLookupKey2, createdWorkload2)).To(testing.BeNotFoundError())
+						g.Expect(k8sClient.Get(ctx, wlLookupKey2, createdWorkload2)).To(utiltesting.BeNotFoundError())
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 
@@ -533,7 +533,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 						g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(2)))
-						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+						g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				})
 
@@ -609,7 +609,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(2)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -642,7 +642,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					createdLeaderWorkerSet := &leaderworkersetv1.LeaderWorkerSet{}
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(2)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -727,7 +727,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lowPriorityLWS), createdLowPriorityLWS)).To(gomega.Succeed())
 					g.Expect(createdLowPriorityLWS.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-					g.Expect(createdLowPriorityLWS.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLowPriorityLWS.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -744,7 +744,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 			ginkgo.By("Check the low priority Workload is admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, lowPriorityWlLookupKey, createdLowPriorityWl)).To(gomega.Succeed())
-					g.Expect(createdLowPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdLowPriorityWl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -766,7 +766,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(highPriorityLWS), createdHighPriorityLWS)).To(gomega.Succeed())
 					g.Expect(createdHighPriorityLWS.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-					g.Expect(createdHighPriorityLWS.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdHighPriorityLWS.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -775,8 +775,8 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lowPriorityLWS), createdLowPriorityLWS)).To(gomega.Succeed())
 					g.Expect(createdLowPriorityLWS.Status.ReadyReplicas).To(gomega.Equal(int32(0)))
-					g.Expect(createdLowPriorityLWS.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Progressing", "GroupsProgressing"))
-					g.Expect(createdLowPriorityLWS.Status.Conditions).To(testing.HaveConditionStatusFalseAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLowPriorityLWS.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Progressing", "GroupsProgressing"))
+					g.Expect(createdLowPriorityLWS.Status.Conditions).To(utiltesting.HaveConditionStatusFalseAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -793,15 +793,15 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 			ginkgo.By("Await for the high priority Workload to be admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, highPriorityWlLookupKey, createdHighPriorityWl)).To(gomega.Succeed())
-					g.Expect(createdHighPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdHighPriorityWl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
 			ginkgo.By("Check the low priority Workload is preempted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, lowPriorityWlLookupKey, createdLowPriorityWl)).To(gomega.Succeed())
-					g.Expect(createdLowPriorityWl.Status.Conditions).To(testing.HaveConditionStatusFalse(kueue.WorkloadAdmitted))
-					g.Expect(createdLowPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadPreempted))
+					g.Expect(createdLowPriorityWl.Status.Conditions).To(utiltesting.HaveConditionStatusFalse(kueue.WorkloadAdmitted))
+					g.Expect(createdLowPriorityWl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadPreempted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -848,7 +848,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 			ginkgo.By("Check the low priority Workload is admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, lowPriorityWlLookupKey, createdLowPriorityWl)).To(gomega.Succeed())
-					g.Expect(createdLowPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdLowPriorityWl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -911,7 +911,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 			ginkgo.By("Await for the high priority Workload to be admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, updatablePriorityWlLookupKey, createdUpdatablePriorityWl)).To(gomega.Succeed())
-					g.Expect(createdUpdatablePriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdUpdatablePriorityWl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -938,7 +938,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -967,7 +967,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(0)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusFalseAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusFalseAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -1008,7 +1008,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(int32(1)))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -1016,7 +1016,7 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
 					g.Expect(createdWorkload.UID).Should(gomega.Equal(createdWorkloadUID))
-					g.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
diff --git a/test/e2e/singlecluster/metrics_test.go b/test/e2e/singlecluster/metrics_test.go
index 6dbb0a0ee..0593fcc01 100644
--- a/test/e2e/singlecluster/metrics_test.go
+++ b/test/e2e/singlecluster/metrics_test.go
@@ -261,6 +261,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			createdJob = testingjob.MakeJob("admission-checked-job", ns.Name).
 				Queue(kueue.LocalQueueName(localQueue.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				RequestAndLimit(corev1.ResourceCPU, "1").
 				Obj()
 			util.MustCreate(ctx, k8sClient, createdJob)
@@ -295,7 +296,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 					workload.SetAdmissionCheckState(&patch.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:  kueue.AdmissionCheckReference(admissionCheck.Name),
 						State: kueue.CheckStateReady,
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().
 						Patch(ctx, patch, client.Apply, client.FieldOwner("test-admission-check-controller"), client.ForceOwnership)).
 						Should(gomega.Succeed())
@@ -404,6 +405,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			lowerJob1 = testingjob.MakeJob("lower-job-1", ns.Name).
 				Queue(kueue.LocalQueueName(localQueue1.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				RequestAndLimit(corev1.ResourceCPU, "1").
 				Obj()
 			util.MustCreate(ctx, k8sClient, lowerJob1)
@@ -423,6 +425,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			lowerJob2 = testingjob.MakeJob("lower-job-2", ns.Name).
 				Queue(kueue.LocalQueueName(localQueue2.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				RequestAndLimit(corev1.ResourceCPU, "1").
 				Obj()
 			util.MustCreate(ctx, k8sClient, lowerJob2)
@@ -442,6 +445,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			blockerJob = testingjob.MakeJob("blocker", ns.Name).
 				Queue(kueue.LocalQueueName(localQueue2.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				PriorityClass(highPriorityClass.Name).
 				RequestAndLimit(corev1.ResourceCPU, "3").
 				Obj()
@@ -462,6 +466,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			higherJob1 = testingjob.MakeJob("high-large-1", ns.Name).
 				Queue(kueue.LocalQueueName(localQueue1.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				PriorityClass(highPriorityClass.Name).
 				RequestAndLimit(corev1.ResourceCPU, "4").
 				Obj()
@@ -469,6 +474,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 
 			higherJob2 = testingjob.MakeJob("high-large-2", ns.Name).
 				Queue(kueue.LocalQueueName(localQueue2.Name)).
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				PriorityClass(highPriorityClass.Name).
 				RequestAndLimit(corev1.ResourceCPU, "4").
 				Obj()
diff --git a/test/e2e/singlecluster/pod_test.go b/test/e2e/singlecluster/pod_test.go
index b78052bcd..c7c7d2145 100644
--- a/test/e2e/singlecluster/pod_test.go
+++ b/test/e2e/singlecluster/pod_test.go
@@ -33,7 +33,7 @@ import (
 	controllerconsts "sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobs/pod"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	podtesting "sigs.k8s.io/kueue/pkg/util/testingjobs/pod"
 	"sigs.k8s.io/kueue/test/util"
@@ -117,7 +117,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					for _, p := range group {
 						var pCopy corev1.Pod
-						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(p), &pCopy)).To(testing.BeNotFoundError())
+						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(p), &pCopy)).To(utiltesting.BeNotFoundError())
 					}
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				util.ExpectWorkloadsFinalizedOrGone(ctx, k8sClient, gKey)
@@ -151,7 +151,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					for _, origPod := range group[:2] {
 						var p corev1.Pod
-						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(origPod), &p)).To(testing.BeNotFoundError())
+						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(origPod), &p)).To(utiltesting.BeNotFoundError())
 					}
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -356,7 +356,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 					var p corev1.Pod
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(rep), &p)).To(gomega.Succeed())
 					g.Expect(p.Spec.SchedulingGates).To(gomega.BeEmpty())
-					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(group[0]), &p)).To(testing.BeNotFoundError())
+					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(group[0]), &p)).To(utiltesting.BeNotFoundError())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -395,7 +395,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					for _, p := range group {
 						var pCopy corev1.Pod
-						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(p), &pCopy)).To(testing.BeNotFoundError())
+						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(p), &pCopy)).To(utiltesting.BeNotFoundError())
 					}
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 				util.ExpectWorkloadsFinalizedOrGone(ctx, k8sClient, gKey)
@@ -413,7 +413,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 				eventWatcher.Stop()
 			})
 
-			highPriorityClass := testing.MakePriorityClass("high").PriorityValue(100).Obj()
+			highPriorityClass := utiltesting.MakePriorityClass("high").PriorityValue(100).Obj()
 			util.MustCreate(ctx, k8sClient, highPriorityClass)
 			ginkgo.DeferCleanup(func() {
 				gomega.Expect(k8sClient.Delete(ctx, highPriorityClass)).To(gomega.Succeed())
@@ -505,7 +505,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 					var p corev1.Pod
 					for _, origPod := range defaultPriorityGroup {
 						origKey := client.ObjectKeyFromObject(origPod)
-						g.Expect(k8sClient.Get(ctx, origKey, &p)).To(testing.BeNotFoundError())
+						g.Expect(k8sClient.Get(ctx, origKey, &p)).To(utiltesting.BeNotFoundError())
 					}
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -609,7 +609,7 @@ var _ = ginkgo.Describe("Pod groups", func() {
 				gomega.Expect(k8sClient.Delete(ctx, &p)).To(gomega.Succeed())
 
 				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, pKey, &corev1.Pod{})).To(testing.BeNotFoundError())
+					g.Expect(k8sClient.Get(ctx, pKey, &corev1.Pod{})).To(utiltesting.BeNotFoundError())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
 				gKey := client.ObjectKey{Namespace: ns.Name, Name: "test-group"}
diff --git a/test/e2e/singlecluster/statefulset_test.go b/test/e2e/singlecluster/statefulset_test.go
index d2d24c3c8..1d8f4da4a 100644
--- a/test/e2e/singlecluster/statefulset_test.go
+++ b/test/e2e/singlecluster/statefulset_test.go
@@ -30,7 +30,7 @@ import (
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	controllerconstants "sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/controller/jobs/statefulset"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	statefulsettesting "sigs.k8s.io/kueue/pkg/util/testingjobs/statefulset"
 	"sigs.k8s.io/kueue/test/util"
@@ -489,7 +489,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 			ginkgo.By("Check the low-priority Workload is created and admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, lowPriorityWlKey, createdLowPriorityWl)).To(gomega.Succeed())
-					g.Expect(createdLowPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdLowPriorityWl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -534,7 +534,7 @@ var _ = ginkgo.Describe("StatefulSet integration", func() {
 			ginkgo.By("Await for the high-priority Workload to be admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, highPriorityWlKey, createdHighPriorityWl)).To(gomega.Succeed())
-					g.Expect(createdHighPriorityWl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
+					g.Expect(createdHighPriorityWl.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
diff --git a/test/e2e/singlecluster/suite_test.go b/test/e2e/singlecluster/suite_test.go
index afe32b742..5c47eb939 100644
--- a/test/e2e/singlecluster/suite_test.go
+++ b/test/e2e/singlecluster/suite_test.go
@@ -27,7 +27,6 @@ import (
 	"github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega"
 	"k8s.io/client-go/rest"
-	"k8s.io/utils/clock"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueueclientset "sigs.k8s.io/kueue/client-go/clientset/versioned"
@@ -37,7 +36,6 @@ import (
 
 var (
 	kueuectlPath                 = filepath.Join("..", "..", "..", "bin", "kubectl-kueue")
-	realClock                    = clock.RealClock{}
 	k8sClient                    client.WithWatch
 	cfg                          *rest.Config
 	restClient                   *rest.RESTClient
diff --git a/test/e2e/singlecluster/tas_test.go b/test/e2e/singlecluster/tas_test.go
index 43f568aca..e04cc768e 100644
--- a/test/e2e/singlecluster/tas_test.go
+++ b/test/e2e/singlecluster/tas_test.go
@@ -34,7 +34,7 @@ import (
 	podcontroller "sigs.k8s.io/kueue/pkg/controller/jobs/pod"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
 	workloadtrainjob "sigs.k8s.io/kueue/pkg/controller/jobs/trainjob"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
 	testingjobset "sigs.k8s.io/kueue/pkg/util/testingjobs/jobset"
@@ -98,9 +98,6 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 				Queue(kueue.LocalQueueName(localQueue.Name)).
 				RequestAndLimit(corev1.ResourceCPU, "700m").
 				RequestAndLimit(corev1.ResourceMemory, "20Mi").
-				Obj()
-			jobKey := client.ObjectKeyFromObject(sampleJob)
-			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
 				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, corev1.LabelHostname).
 				Image(util.GetAgnHostImage(), util.BehaviorExitFast).
 				Obj()
@@ -109,6 +106,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 			createdWorkload := &kueue.Workload{}
 
 			// The job might have finished at this point. That shouldn't be a problem for the purpose of this test
+			jobKey := client.ObjectKeyFromObject(sampleJob)
 			util.ExpectJobUnsuspendedWithNodeSelectors(ctx, k8sClient, jobKey, map[string]string{
 				"instance-type": "on-demand",
 			})
@@ -141,7 +139,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -276,7 +274,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -377,7 +375,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -441,7 +439,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -555,7 +553,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
diff --git a/test/e2e/singlecluster/trainjob_test.go b/test/e2e/singlecluster/trainjob_test.go
index 9efa0daa7..256289d15 100644
--- a/test/e2e/singlecluster/trainjob_test.go
+++ b/test/e2e/singlecluster/trainjob_test.go
@@ -27,7 +27,7 @@ import (
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	workloadtrainjob "sigs.k8s.io/kueue/pkg/controller/jobs/trainjob"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingtrainjob "sigs.k8s.io/kueue/pkg/util/testingjobs/trainjob"
 	"sigs.k8s.io/kueue/test/util"
@@ -90,7 +90,7 @@ var _ = ginkgo.Describe("TrainJob", func() {
 			ginkgo.By("Ensuring that a workload is created and the job admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-					g.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatus(kueue.WorkloadAdmitted, metav1.ConditionTrue))
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatus(kueue.WorkloadAdmitted, metav1.ConditionTrue))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -104,7 +104,7 @@ var _ = ginkgo.Describe("TrainJob", func() {
 			ginkgo.By("Waiting for the trainjob to finish", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-					g.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason(kueue.WorkloadFinished, kueue.WorkloadFinishedReasonSucceeded))
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason(kueue.WorkloadFinished, kueue.WorkloadFinishedReasonSucceeded))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -173,7 +173,7 @@ var _ = ginkgo.Describe("TrainJob", func() {
 			ginkgo.By("Ensuring that a workload is created and the job admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-					g.Expect(createdWorkload.Status.Conditions).To(testing.HaveConditionStatus(kueue.WorkloadAdmitted, metav1.ConditionTrue))
+					g.Expect(createdWorkload.Status.Conditions).To(utiltesting.HaveConditionStatus(kueue.WorkloadAdmitted, metav1.ConditionTrue))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
diff --git a/test/e2e/singlecluster/visibility_test.go b/test/e2e/singlecluster/visibility_test.go
index 60912474e..9bcff13e8 100644
--- a/test/e2e/singlecluster/visibility_test.go
+++ b/test/e2e/singlecluster/visibility_test.go
@@ -31,7 +31,7 @@ import (
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	visibility "sigs.k8s.io/kueue/apis/visibility/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
 	"sigs.k8s.io/kueue/test/util"
@@ -92,13 +92,13 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 			localQueueB = utiltestingapi.MakeLocalQueue("b", nsA.Name).ClusterQueue(clusterQueue.Name).Obj()
 			util.MustCreate(ctx, k8sClient, localQueueB)
 
-			highPriorityClass = testing.MakePriorityClass("high").PriorityValue(100).Obj()
+			highPriorityClass = utiltesting.MakePriorityClass("high").PriorityValue(100).Obj()
 			util.MustCreate(ctx, k8sClient, highPriorityClass)
 
-			midPriorityClass = testing.MakePriorityClass("mid").PriorityValue(75).Obj()
+			midPriorityClass = utiltesting.MakePriorityClass("mid").PriorityValue(75).Obj()
 			util.MustCreate(ctx, k8sClient, midPriorityClass)
 
-			lowPriorityClass = testing.MakePriorityClass("low").PriorityValue(50).Obj()
+			lowPriorityClass = utiltesting.MakePriorityClass("low").PriorityValue(50).Obj()
 			util.MustCreate(ctx, k8sClient, lowPriorityClass)
 
 			ginkgo.By("Schedule a job that when admitted workload blocks the queue", func() {
@@ -541,7 +541,7 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 			ginkgo.By("Wait for ResourceNotFound error instead of Forbidden to make sure the role bindings work", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					_, err := impersonatedVisibilityClient.ClusterQueues().GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-					g.Expect(err).Should(testing.BeNotFoundError())
+					g.Expect(err).Should(utiltesting.BeNotFoundError())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -553,11 +553,11 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 		ginkgo.It("Should return an appropriate error", func() {
 			ginkgo.By("Returning a ResourceNotFound error for a nonexistent ClusterQueue", func() {
 				_, err := impersonatedVisibilityClient.ClusterQueues().GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-				gomega.Expect(err).Should(testing.BeNotFoundError())
+				gomega.Expect(err).Should(utiltesting.BeNotFoundError())
 			})
 			ginkgo.By("Returning a ResourceNotFound error for a nonexistent LocalQueue", func() {
 				_, err := impersonatedVisibilityClient.LocalQueues(nsA.Name).GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-				gomega.Expect(err).Should(testing.BeNotFoundError())
+				gomega.Expect(err).Should(utiltesting.BeNotFoundError())
 			})
 		})
 	})
@@ -577,7 +577,7 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 			ginkgo.By("Wait for ResourceNotFound error instead of Forbidden to make sure the role bindings work", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					_, err := impersonatedVisibilityClient.LocalQueues(nsA.Name).GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-					g.Expect(err).Should(testing.BeNotFoundError())
+					g.Expect(err).Should(utiltesting.BeNotFoundError())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -589,15 +589,15 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 		ginkgo.It("Should return an appropriate error", func() {
 			ginkgo.By("Returning a Forbidden error due to insufficient permissions for the ClusterQueue request", func() {
 				_, err := impersonatedVisibilityClient.ClusterQueues().GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-				gomega.Expect(err).Should(testing.BeForbiddenError())
+				gomega.Expect(err).Should(utiltesting.BeForbiddenError())
 			})
 			ginkgo.By("Returning a ResourceNotFound error for a nonexistent LocalQueue", func() {
 				_, err := impersonatedVisibilityClient.LocalQueues(nsA.Name).GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-				gomega.Expect(err).Should(testing.BeNotFoundError())
+				gomega.Expect(err).Should(utiltesting.BeNotFoundError())
 			})
 			ginkgo.By("Returning a Forbidden error due to insufficient permissions for the LocalQueue request in different namespace", func() {
 				_, err := impersonatedVisibilityClient.LocalQueues("default").GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-				gomega.Expect(err).Should(testing.BeForbiddenError())
+				gomega.Expect(err).Should(utiltesting.BeForbiddenError())
 			})
 		})
 	})
@@ -606,11 +606,11 @@ var _ = ginkgo.Describe("Kueue visibility server", func() {
 		ginkgo.It("Should return an appropriate error", func() {
 			ginkgo.By("Returning a Forbidden error due to insufficient permissions for the ClusterQueue request", func() {
 				_, err := impersonatedVisibilityClient.ClusterQueues().GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-				gomega.Expect(err).Should(testing.BeForbiddenError())
+				gomega.Expect(err).Should(utiltesting.BeForbiddenError())
 			})
 			ginkgo.By("Returning a Forbidden error due to insufficient permissions for the LocalQueue request", func() {
 				_, err := impersonatedVisibilityClient.LocalQueues(nsA.Name).GetPendingWorkloadsSummary(ctx, "non-existent", metav1.GetOptions{})
-				gomega.Expect(err).Should(testing.BeForbiddenError())
+				gomega.Expect(err).Should(utiltesting.BeForbiddenError())
 			})
 		})
 	})
diff --git a/test/e2e/tas/appwrapper_test.go b/test/e2e/tas/appwrapper_test.go
index f00273142..32159e1f9 100644
--- a/test/e2e/tas/appwrapper_test.go
+++ b/test/e2e/tas/appwrapper_test.go
@@ -26,7 +26,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	awtesting "sigs.k8s.io/kueue/pkg/util/testingjobs/appwrapper"
 	utiltestingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
@@ -91,7 +91,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for AppWrapper", func() {
 						RequestAndLimit(extraResource, "1").
 						Suspend(false).
 						Image(util.GetAgnHostImage(), util.BehaviorExitFast).
-						PodAnnotation(kueue.PodSetPreferredTopologyAnnotation, testing.DefaultRackTopologyLevel).
+						PodAnnotation(kueue.PodSetPreferredTopologyAnnotation, utiltesting.DefaultRackTopologyLevel).
 						SetTypeMeta().Obj(),
 				}).
 				Queue(localQueue.Name).
@@ -133,7 +133,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for AppWrapper", func() {
 				Indexed(true).
 				Suspend(false).
 				RequestAndLimit(extraResource, "1").
-				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
+				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, utiltesting.DefaultBlockTopologyLevel).
 				Image(util.GetAgnHostImage(), util.BehaviorExitFast).
 				SetTypeMeta().
 				Obj()
diff --git a/test/e2e/tas/hotswap_test.go b/test/e2e/tas/hotswap_test.go
index 6ce198734..a8d56c728 100644
--- a/test/e2e/tas/hotswap_test.go
+++ b/test/e2e/tas/hotswap_test.go
@@ -31,7 +31,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
 	testingjobset "sigs.k8s.io/kueue/pkg/util/testingjobs/jobset"
@@ -129,8 +129,8 @@ var _ = ginkgo.Describe("Hotswap for Topology Aware Scheduling", ginkgo.Ordered,
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
 						PodAnnotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation:     testing.DefaultBlockTopologyLevel,
-							kueue.PodSetSliceRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation:     utiltesting.DefaultBlockTopologyLevel,
+							kueue.PodSetSliceRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetSliceSizeAnnotation:             "3",
 						},
 					},
@@ -207,8 +207,8 @@ var _ = ginkgo.Describe("Hotswap for Topology Aware Scheduling", ginkgo.Ordered,
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
 						PodAnnotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation:     testing.DefaultBlockTopologyLevel,
-							kueue.PodSetSliceRequiredTopologyAnnotation: testing.DefaultRackTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation:     utiltesting.DefaultBlockTopologyLevel,
+							kueue.PodSetSliceRequiredTopologyAnnotation: utiltesting.DefaultRackTopologyLevel,
 							kueue.PodSetSliceSizeAnnotation:             "2",
 						},
 					},
diff --git a/test/e2e/tas/job_test.go b/test/e2e/tas/job_test.go
index 2bae3bed4..27d01b210 100644
--- a/test/e2e/tas/job_test.go
+++ b/test/e2e/tas/job_test.go
@@ -30,7 +30,7 @@ import (
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
 	"sigs.k8s.io/kueue/pkg/workload"
@@ -99,7 +99,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				RequestAndLimit(extraResource, "1").
 				Obj()
 			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
-				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, testing.DefaultRackTopologyLevel).
+				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, utiltesting.DefaultRackTopologyLevel).
 				Image(util.GetAgnHostImage(), util.BehaviorExitFast).
 				Obj()
 			util.MustCreate(ctx, k8sClient, sampleJob)
@@ -120,9 +120,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Parallelism(3).
 				Completions(3).
 				RequestAndLimit(extraResource, "1").
-				Obj()
-			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
-				PodAnnotation(kueue.PodSetPreferredTopologyAnnotation, testing.DefaultRackTopologyLevel).
+				PodAnnotation(kueue.PodSetPreferredTopologyAnnotation, utiltesting.DefaultRackTopologyLevel).
 				Image(util.GetAgnHostImage(), util.BehaviorExitFast).
 				Obj()
 			util.MustCreate(ctx, k8sClient, sampleJob)
@@ -161,7 +159,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -172,9 +170,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Parallelism(3).
 				Completions(3).
 				RequestAndLimit(extraResource, "1").
-				Obj()
-			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
-				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
+				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, utiltesting.DefaultBlockTopologyLevel).
 				Image(util.GetAgnHostImage(), util.BehaviorExitFast).
 				Obj()
 			util.MustCreate(ctx, k8sClient, sampleJob)
@@ -214,7 +210,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(createdWorkload)).Should(gomega.BeTrue())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -225,9 +221,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Parallelism(2).
 				Completions(3).
 				RequestAndLimit(extraResource, "1").
-				Obj()
-			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
-				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
+				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, utiltesting.DefaultBlockTopologyLevel).
 				Image(util.GetAgnHostImage(), util.BehaviorExitFast).
 				Obj()
 			util.MustCreate(ctx, k8sClient, sampleJob)
@@ -240,7 +234,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
 					g.Expect(createdWorkload.Status.Admission.PodSetAssignments).Should(gomega.HaveLen(1))
 					g.Expect(createdWorkload.Status.Admission.PodSetAssignments[0].TopologyAssignment).ShouldNot(gomega.BeNil())
-					g.Expect(createdWorkload.Status.Conditions).Should(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
+					g.Expect(createdWorkload.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -253,9 +247,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Job", func() {
 				Completions(int32(numPods)).
 				Indexed(true).
 				RequestAndLimit(extraResource, "1").
-				Obj()
-			sampleJob = (&testingjob.JobWrapper{Job: *sampleJob}).
-				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
+				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, utiltesting.DefaultBlockTopologyLevel).
 				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				Obj()
 			util.MustCreate(ctx, k8sClient, sampleJob)
diff --git a/test/e2e/tas/jobset_test.go b/test/e2e/tas/jobset_test.go
index df3f6e34e..514155e28 100644
--- a/test/e2e/tas/jobset_test.go
+++ b/test/e2e/tas/jobset_test.go
@@ -29,7 +29,7 @@ import (
 	jobset "sigs.k8s.io/jobset/api/jobset/v1alpha2"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjobset "sigs.k8s.io/kueue/pkg/util/testingjobs/jobset"
 	"sigs.k8s.io/kueue/test/util"
@@ -98,7 +98,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for JobSet", func() {
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
 						PodAnnotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 						},
 					},
 				).
@@ -161,8 +161,8 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for JobSet", func() {
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
 						PodAnnotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation:     testing.DefaultBlockTopologyLevel,
-							kueue.PodSetSliceRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation:     utiltesting.DefaultBlockTopologyLevel,
+							kueue.PodSetSliceRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetSliceSizeAnnotation:             "3",
 						},
 					},
@@ -226,7 +226,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for JobSet", func() {
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
 						PodAnnotations: map[string]string{
-							kueue.PodSetSliceRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetSliceRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetSliceSizeAnnotation:             "3",
 						},
 					},
diff --git a/test/e2e/tas/leaderworkerset_test.go b/test/e2e/tas/leaderworkerset_test.go
index 18fe68f40..5be87e3b0 100644
--- a/test/e2e/tas/leaderworkerset_test.go
+++ b/test/e2e/tas/leaderworkerset_test.go
@@ -29,7 +29,7 @@ import (
 	leaderworkersetv1 "sigs.k8s.io/lws/api/leaderworkerset/v1"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	leaderworkersettesting "sigs.k8s.io/kueue/pkg/util/testingjobs/leaderworkerset"
 	"sigs.k8s.io/kueue/test/util"
@@ -92,7 +92,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 				WorkerTemplate(corev1.PodTemplateSpec{
 					ObjectMeta: metav1.ObjectMeta{
 						Annotations: map[string]string{
-							kueue.PodSetRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 						},
 					},
 					Spec: corev1.PodSpec{
@@ -124,7 +124,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(replicas))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -185,7 +185,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 				WorkerTemplate(corev1.PodTemplateSpec{
 					ObjectMeta: metav1.ObjectMeta{
 						Annotations: map[string]string{
-							kueue.PodSetRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetGroupName:                  "same-group",
 						},
 					},
@@ -210,7 +210,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 				LeaderTemplate(corev1.PodTemplateSpec{
 					ObjectMeta: metav1.ObjectMeta{
 						Annotations: map[string]string{
-							kueue.PodSetRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetGroupName:                  "same-group",
 						},
 					},
@@ -243,7 +243,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(replicas))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -294,7 +294,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 				WorkerTemplate(corev1.PodTemplateSpec{
 					ObjectMeta: metav1.ObjectMeta{
 						Annotations: map[string]string{
-							kueue.PodSetRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetGroupName:                  "same-group",
 						},
 					},
@@ -321,7 +321,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 				LeaderTemplate(corev1.PodTemplateSpec{
 					ObjectMeta: metav1.ObjectMeta{
 						Annotations: map[string]string{
-							kueue.PodSetRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetGroupName:                  "same-group",
 						},
 					},
@@ -354,7 +354,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
 					g.Expect(createdLeaderWorkerSet.Status.ReadyReplicas).To(gomega.Equal(replicas))
-					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(testing.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
+					g.Expect(createdLeaderWorkerSet.Status.Conditions).To(utiltesting.HaveConditionStatusTrueAndReason("Available", "AllGroupsReady"))
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
diff --git a/test/e2e/tas/mpijob_test.go b/test/e2e/tas/mpijob_test.go
index ccd8585af..2f902f9bb 100644
--- a/test/e2e/tas/mpijob_test.go
+++ b/test/e2e/tas/mpijob_test.go
@@ -29,7 +29,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingmpijob "sigs.k8s.io/kueue/pkg/util/testingjobs/mpijob"
 	"sigs.k8s.io/kueue/test/util"
@@ -97,7 +97,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for MPIJob", func() {
 						ReplicaCount:  launcherReplicas,
 						RestartPolicy: corev1.RestartPolicyOnFailure,
 						Annotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation: testing.DefaultRackTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation: utiltesting.DefaultRackTopologyLevel,
 						},
 					},
 					testingmpijob.MPIJobReplicaSpecRequirement{
@@ -105,7 +105,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for MPIJob", func() {
 						ReplicaCount:  workerReplicas,
 						RestartPolicy: corev1.RestartPolicyOnFailure,
 						Annotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 						},
 					},
 				).
diff --git a/test/e2e/tas/pod_group_test.go b/test/e2e/tas/pod_group_test.go
index 7e82a6c88..9e254fba5 100644
--- a/test/e2e/tas/pod_group_test.go
+++ b/test/e2e/tas/pod_group_test.go
@@ -24,7 +24,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingpod "sigs.k8s.io/kueue/pkg/util/testingjobs/pod"
 	"sigs.k8s.io/kueue/test/util"
@@ -86,7 +86,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Pod group", func() {
 				RequestAndLimit(extraResource, "1").
 				Limit(extraResource, "1").
 				Image(util.GetAgnHostImage(), util.BehaviorExitFast).
-				Annotation(kueue.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel)
+				Annotation(kueue.PodSetRequiredTopologyAnnotation, utiltesting.DefaultBlockTopologyLevel)
 			podGroup := basePod.MakeIndexedGroup(numPods)
 
 			for _, pod := range podGroup {
@@ -134,6 +134,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Pod group", func() {
 			numPods := 4
 			basePod := testingpod.MakePod("test-pod", ns.Name).
 				Queue("test-queue").
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				Request(extraResource, "1").
 				Limit(extraResource, "1")
 			podGroup := basePod.MakeIndexedGroup(numPods)
@@ -216,6 +217,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for Pod group", func() {
 			numPods := 4
 			basePod := testingpod.MakePod("test-pod", ns.Name).
 				Queue("test-queue").
+				Image(util.GetAgnHostImage(), util.BehaviorWaitForDeletion).
 				Request(extraResource, "1").
 				Limit(extraResource, "1")
 			podGroup := basePod.MakeIndexedGroup(numPods)
diff --git a/test/e2e/tas/pytorch_test.go b/test/e2e/tas/pytorch_test.go
index 9da357209..40574c843 100644
--- a/test/e2e/tas/pytorch_test.go
+++ b/test/e2e/tas/pytorch_test.go
@@ -28,7 +28,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingpytorchjob "sigs.k8s.io/kueue/pkg/util/testingjobs/pytorchjob"
 	"sigs.k8s.io/kueue/test/util"
@@ -96,7 +96,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for PyTorchJob", func() {
 						ReplicaCount:  masterReplicas,
 						RestartPolicy: kftraining.RestartPolicyOnFailure,
 						Annotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation: testing.DefaultRackTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation: utiltesting.DefaultRackTopologyLevel,
 						},
 					},
 					testingpytorchjob.PyTorchReplicaSpecRequirement{
@@ -104,7 +104,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for PyTorchJob", func() {
 						ReplicaCount:  workerReplicas,
 						RestartPolicy: kftraining.RestartPolicyOnFailure,
 						Annotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 						},
 					},
 				).
diff --git a/test/e2e/tas/rayjob_test.go b/test/e2e/tas/rayjob_test.go
index eb7d9cfbe..364c0416a 100644
--- a/test/e2e/tas/rayjob_test.go
+++ b/test/e2e/tas/rayjob_test.go
@@ -29,7 +29,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingrayjob "sigs.k8s.io/kueue/pkg/util/testingjobs/rayjob"
 	"sigs.k8s.io/kueue/test/util"
@@ -116,7 +116,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for RayJob", ginkgo.Ordered, fu
 							},
 							ObjectMeta: metav1.ObjectMeta{
 								Annotations: map[string]string{
-									kueue.PodSetPreferredTopologyAnnotation: testing.DefaultRackTopologyLevel,
+									kueue.PodSetPreferredTopologyAnnotation: utiltesting.DefaultRackTopologyLevel,
 								},
 							},
 						},
@@ -148,7 +148,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for RayJob", ginkgo.Ordered, fu
 							},
 							ObjectMeta: metav1.ObjectMeta{
 								Annotations: map[string]string{
-									kueue.PodSetPreferredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+									kueue.PodSetPreferredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 								},
 							},
 						},
@@ -174,7 +174,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for RayJob", ginkgo.Ordered, fu
 					},
 					ObjectMeta: metav1.ObjectMeta{
 						Annotations: map[string]string{
-							kueue.PodSetRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 						},
 					},
 				}).
diff --git a/test/e2e/tas/statefulset_test.go b/test/e2e/tas/statefulset_test.go
index 0cf805c7e..2033360a7 100644
--- a/test/e2e/tas/statefulset_test.go
+++ b/test/e2e/tas/statefulset_test.go
@@ -25,7 +25,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	"sigs.k8s.io/kueue/pkg/util/testingjobs/statefulset"
 	"sigs.k8s.io/kueue/test/util"
@@ -81,7 +81,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for StatefulSet", func() {
 				RequestAndLimit(extraResource, "1").
 				Replicas(replicas).
 				Queue(localQueue.Name).
-				PodTemplateSpecAnnotation(kueue.PodSetRequiredTopologyAnnotation, testing.DefaultBlockTopologyLevel).
+				PodTemplateSpecAnnotation(kueue.PodSetRequiredTopologyAnnotation, utiltesting.DefaultBlockTopologyLevel).
 				TerminationGracePeriod(1).
 				Obj()
 			util.MustCreate(ctx, k8sClient, sts)
diff --git a/test/e2e/tas/trainjob_test.go b/test/e2e/tas/trainjob_test.go
index 6255454e2..5501014bb 100644
--- a/test/e2e/tas/trainjob_test.go
+++ b/test/e2e/tas/trainjob_test.go
@@ -30,7 +30,7 @@ import (
 	jobset "sigs.k8s.io/jobset/api/jobset/v1alpha2"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	testingjobset "sigs.k8s.io/kueue/pkg/util/testingjobs/jobset"
 	testingtrainjob "sigs.k8s.io/kueue/pkg/util/testingjobs/trainjob"
@@ -101,7 +101,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for TrainJob", func() {
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
 						PodAnnotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 						},
 					}).
 				RequestAndLimit("node", extraResource, "1").Obj().Spec)
@@ -171,8 +171,8 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for TrainJob", func() {
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
 						PodAnnotations: map[string]string{
-							kueue.PodSetPreferredTopologyAnnotation:     testing.DefaultBlockTopologyLevel,
-							kueue.PodSetSliceRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetPreferredTopologyAnnotation:     utiltesting.DefaultBlockTopologyLevel,
+							kueue.PodSetSliceRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetSliceSizeAnnotation:             "3",
 						},
 					}).
@@ -243,7 +243,7 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for TrainJob", func() {
 						Parallelism: int32(parallelism),
 						Completions: int32(parallelism),
 						PodAnnotations: map[string]string{
-							kueue.PodSetSliceRequiredTopologyAnnotation: testing.DefaultBlockTopologyLevel,
+							kueue.PodSetSliceRequiredTopologyAnnotation: utiltesting.DefaultBlockTopologyLevel,
 							kueue.PodSetSliceSizeAnnotation:             "3",
 						},
 					}).
diff --git a/test/integration/multikueue/dispatcher_test.go b/test/integration/multikueue/dispatcher_test.go
index 6e1348ded..8d51c379c 100644
--- a/test/integration/multikueue/dispatcher_test.go
+++ b/test/integration/multikueue/dispatcher_test.go
@@ -27,7 +27,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/utils/clock"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 
@@ -63,7 +62,6 @@ var _ = ginkgo.Describe("MultiKueueDispatcherIncremental", ginkgo.Ordered, ginkg
 
 		worker2Cq *kueue.ClusterQueue
 		worker2Lq *kueue.LocalQueue
-		realClock = clock.RealClock{}
 	)
 
 	ginkgo.BeforeAll(func() {
@@ -211,13 +209,13 @@ var _ = ginkgo.Describe("MultiKueueDispatcherIncremental", ginkgo.Ordered, ginkg
 		ginkgo.By("setting the check conditions for eviction", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, createdWorkload, realClock, func() (*kueue.Workload, bool, error) {
+				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, createdWorkload, util.RealClock, func() (*kueue.Workload, bool, error) {
 					acs := kueue.AdmissionCheckState{
 						Name:    kueue.AdmissionCheckReference(multiKueueAC.Name),
 						State:   kueue.CheckStateRejected,
 						Message: "check rejected",
 					}
-					return createdWorkload, workload.SetAdmissionCheckState(&createdWorkload.Status.AdmissionChecks, acs, realClock), nil
+					return createdWorkload, workload.SetAdmissionCheckState(&createdWorkload.Status.AdmissionChecks, acs, util.RealClock), nil
 				})).To(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
@@ -246,7 +244,6 @@ var _ = ginkgo.Describe("MultiKueueDispatcherExternal", ginkgo.Ordered, ginkgo.C
 		multiKueueAC             *kueue.AdmissionCheck
 		managerCq                *kueue.ClusterQueue
 		managerLq                *kueue.LocalQueue
-		realClock                = clock.RealClock{}
 
 		worker1Cq *kueue.ClusterQueue
 		worker1Lq *kueue.LocalQueue
@@ -379,7 +376,7 @@ var _ = ginkgo.Describe("MultiKueueDispatcherExternal", ginkgo.Ordered, ginkgo.C
 			gomega.Eventually(func(g gomega.Gomega) {
 				managerWl := &kueue.Workload{}
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
-				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, managerWl, realClock, func() (*kueue.Workload, bool, error) {
+				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, managerWl, util.RealClock, func() (*kueue.Workload, bool, error) {
 					managerWl.Status.NominatedClusterNames = []string{workerCluster2.Name}
 					return managerWl, true, nil
 				})).To(gomega.Succeed())
@@ -409,7 +406,7 @@ var _ = ginkgo.Describe("MultiKueueDispatcherExternal", ginkgo.Ordered, ginkgo.C
 			managerWl := &kueue.Workload{}
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
-				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, managerWl, realClock, func() (*kueue.Workload, bool, error) {
+				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, managerWl, util.RealClock, func() (*kueue.Workload, bool, error) {
 					managerWl.Status.NominatedClusterNames = []string{workerCluster1.Name, workerCluster2.Name}
 					return managerWl, true, nil
 				})).To(gomega.Succeed())
@@ -451,13 +448,13 @@ var _ = ginkgo.Describe("MultiKueueDispatcherExternal", ginkgo.Ordered, ginkgo.C
 		ginkgo.By("setting the check conditions for eviction", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, createdWorkload, realClock, func() (*kueue.Workload, bool, error) {
+				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, createdWorkload, util.RealClock, func() (*kueue.Workload, bool, error) {
 					acs := kueue.AdmissionCheckState{
 						Name:    kueue.AdmissionCheckReference(multiKueueAC.Name),
 						State:   kueue.CheckStateRejected,
 						Message: "check rejected",
 					}
-					return createdWorkload, workload.SetAdmissionCheckState(&createdWorkload.Status.AdmissionChecks, acs, realClock), nil
+					return createdWorkload, workload.SetAdmissionCheckState(&createdWorkload.Status.AdmissionChecks, acs, util.RealClock), nil
 				})).To(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
@@ -492,7 +489,6 @@ var _ = ginkgo.Describe("MultiKueueDispatcherAllAtOnce", ginkgo.Ordered, ginkgo.
 
 		worker2Cq *kueue.ClusterQueue
 		worker2Lq *kueue.LocalQueue
-		realClock = clock.RealClock{}
 	)
 
 	ginkgo.BeforeAll(func() {
@@ -663,7 +659,7 @@ var _ = ginkgo.Describe("MultiKueueDispatcherAllAtOnce", ginkgo.Ordered, ginkgo.
 		ginkgo.By("Resetting ClusterName field in the manager", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, createdWorkload, realClock, func() (*kueue.Workload, bool, error) {
+				g.Expect(workload.PatchAdmissionStatus(managerTestCluster.ctx, managerTestCluster.client, createdWorkload, util.RealClock, func() (*kueue.Workload, bool, error) {
 					createdWorkload.Status.ClusterName = nil
 					return createdWorkload, true, nil
 				})).To(gomega.Succeed())
diff --git a/test/integration/multikueue/jobs_test.go b/test/integration/multikueue/jobs_test.go
index 1505dd1f4..3a6b8fcb3 100644
--- a/test/integration/multikueue/jobs_test.go
+++ b/test/integration/multikueue/jobs_test.go
@@ -35,7 +35,6 @@ import (
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
@@ -1632,7 +1631,6 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 		manager := managerTestCluster
 		worker1 := worker1TestCluster
 		worker2 := worker2TestCluster
-		realClock := clock.RealClock{}
 
 		features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.ElasticJobsViaWorkloadSlices, true)
 
@@ -1765,7 +1763,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 		ginkgo.By("admit the new workload and finish the old workload in the manager cluster", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				oldWorkload := getWorkload(g, manager.ctx, manager.client, workloadKey)
-				g.Expect(workloadslicing.Finish(manager.ctx, manager.client, realClock, oldWorkload, kueue.WorkloadSliceReplaced, "Replaced to accommodate a new slice")).To(gomega.Succeed())
+				g.Expect(workloadslicing.Finish(manager.ctx, manager.client, util.RealClock, oldWorkload, kueue.WorkloadSliceReplaced, "Replaced to accommodate a new slice")).To(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			util.SetQuotaReservation(manager.ctx, manager.client, newWorkloadKey, utiltestingapi.MakeAdmission(managerCq.Name).Obj())
 		})
@@ -1802,7 +1800,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 			util.SetQuotaReservation(worker1.ctx, worker1.client, newWorkloadKey, utiltestingapi.MakeAdmission(managerCq.Name).Obj())
 			gomega.Eventually(func(g gomega.Gomega) {
 				workload := getWorkload(g, worker1.ctx, worker1.client, workloadKey)
-				g.Expect(workloadslicing.Finish(worker1.ctx, worker1.client, realClock, workload, kueue.WorkloadSliceReplaced, "Replaced to accommodate a new slice")).To(gomega.Succeed())
+				g.Expect(workloadslicing.Finish(worker1.ctx, worker1.client, util.RealClock, workload, kueue.WorkloadSliceReplaced, "Replaced to accommodate a new slice")).To(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
 
diff --git a/test/integration/multikueue/no_gc_test.go b/test/integration/multikueue/no_gc_test.go
index 960e77683..2c7c82de6 100644
--- a/test/integration/multikueue/no_gc_test.go
+++ b/test/integration/multikueue/no_gc_test.go
@@ -25,7 +25,6 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 
@@ -62,7 +61,6 @@ var _ = ginkgo.Describe("MultiKueue no GC", ginkgo.Ordered, ginkgo.ContinueOnFai
 
 		worker2Cq *kueue.ClusterQueue
 		worker2Lq *kueue.LocalQueue
-		realClock clock.RealClock
 	)
 
 	ginkgo.BeforeAll(func() {
@@ -258,7 +256,7 @@ var _ = ginkgo.Describe("MultiKueue no GC", ginkgo.Ordered, ginkgo.ContinueOnFai
 				workload.SetAdmissionCheckState(&createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckState{
 					Name:  kueue.AdmissionCheckReference(multiKueueAC.Name),
 					State: kueue.CheckStateRejected,
-				}, realClock)
+				}, util.RealClock)
 				g.Expect(managerTestCluster.client.Status().Update(managerTestCluster.ctx, createdWorkload)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
diff --git a/test/integration/multikueue/tas/suite_test.go b/test/integration/multikueue/tas/suite_test.go
new file mode 100644
index 000000000..fec5e754a
--- /dev/null
+++ b/test/integration/multikueue/tas/suite_test.go
@@ -0,0 +1,230 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package multikueue
+
+import (
+	"context"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/util/sets"
+	versionutil "k8s.io/apimachinery/pkg/util/version"
+	"k8s.io/client-go/discovery"
+	"k8s.io/client-go/rest"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/manager"
+
+	config "sigs.k8s.io/kueue/apis/config/v1beta2"
+	qcache "sigs.k8s.io/kueue/pkg/cache/queue"
+	schdcache "sigs.k8s.io/kueue/pkg/cache/scheduler"
+	"sigs.k8s.io/kueue/pkg/constants"
+	"sigs.k8s.io/kueue/pkg/controller/admissionchecks/multikueue"
+	"sigs.k8s.io/kueue/pkg/controller/admissionchecks/provisioning"
+	"sigs.k8s.io/kueue/pkg/controller/core"
+	"sigs.k8s.io/kueue/pkg/controller/core/indexer"
+	"sigs.k8s.io/kueue/pkg/controller/jobframework"
+	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
+	"sigs.k8s.io/kueue/pkg/controller/tas"
+	tasindexer "sigs.k8s.io/kueue/pkg/controller/tas/indexer"
+	"sigs.k8s.io/kueue/pkg/scheduler"
+	"sigs.k8s.io/kueue/pkg/util/kubeversion"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
+	"sigs.k8s.io/kueue/pkg/webhooks"
+	"sigs.k8s.io/kueue/test/integration/framework"
+	"sigs.k8s.io/kueue/test/util"
+)
+
+const (
+	testingWorkerLostTimeout = 3 * time.Second
+)
+
+type cluster struct {
+	cfg    *rest.Config
+	client client.Client
+	ctx    context.Context
+	fwk    *framework.Framework
+}
+
+func (c *cluster) kubeConfigBytes() ([]byte, error) {
+	return utiltesting.RestConfigToKubeConfig(c.cfg)
+}
+
+var (
+	managerK8sVersion       *versionutil.Version
+	managerTestCluster      cluster
+	worker1TestCluster      cluster
+	worker2TestCluster      cluster
+	managersConfigNamespace *corev1.Namespace
+
+	// makes sure there is only one fwk.Init and setupClient at the same time
+	// since these functions are not thread safe due to adding to the common
+	// schema.
+	mu sync.Mutex
+)
+
+func TestMultiKueue(t *testing.T) {
+	gomega.RegisterFailHandler(ginkgo.Fail)
+	ginkgo.RunSpecs(t,
+		"MultiKueue TAS Suite",
+	)
+}
+
+func createCluster(setupFnc framework.ManagerSetup, apiFeatureGates ...string) cluster {
+	c := cluster{}
+	c.fwk = &framework.Framework{
+		WebhookPath: util.WebhookPath,
+		DepCRDPaths: []string{
+			util.AutoscalerCrds,
+		},
+		APIServerFeatureGates: apiFeatureGates,
+	}
+	mu.Lock()
+	c.cfg = c.fwk.Init()
+	c.ctx, c.client = c.fwk.SetupClient(c.cfg)
+	mu.Unlock()
+
+	// skip the manager setup if setup func is not provided
+	if setupFnc != nil {
+		c.fwk.StartManager(c.ctx, c.cfg, setupFnc)
+	}
+	return c
+}
+
+func managerSetup(ctx context.Context, mgr manager.Manager) {
+	err := indexer.Setup(ctx, mgr.GetFieldIndexer())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	cCache := schdcache.New(mgr.GetClient())
+	queues := qcache.NewManager(mgr.GetClient(), cCache)
+
+	configuration := &config.Configuration{}
+	mgr.GetScheme().Default(configuration)
+
+	failedCtrl, err := core.SetupControllers(mgr, queues, cCache, configuration)
+	gomega.Expect(err).ToNot(gomega.HaveOccurred(), "controller", failedCtrl)
+
+	failedCtrl, err = tas.SetupControllers(mgr, queues, cCache, configuration)
+	gomega.Expect(err).ToNot(gomega.HaveOccurred(), "TAS controller", failedCtrl)
+
+	err = tasindexer.SetupIndexes(ctx, mgr.GetFieldIndexer())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	failedWebhook, err := webhooks.Setup(mgr)
+	gomega.Expect(err).ToNot(gomega.HaveOccurred(), "webhook", failedWebhook)
+
+	err = workloadjob.SetupIndexes(ctx, mgr.GetFieldIndexer())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	jobReconciler, err := workloadjob.NewReconciler(
+		ctx,
+		mgr.GetClient(),
+		mgr.GetFieldIndexer(),
+		mgr.GetEventRecorderFor(constants.JobControllerName))
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+	err = jobReconciler.SetupWithManager(mgr)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	err = workloadjob.SetupWebhook(mgr, jobframework.WithCache(cCache), jobframework.WithQueues(queues))
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	err = provisioning.SetupIndexer(ctx, mgr.GetFieldIndexer())
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	reconciler, err := provisioning.NewController(
+		mgr.GetClient(),
+		mgr.GetEventRecorderFor("kueue-provisioning-request-controller"))
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	err = reconciler.SetupWithManager(mgr)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	sched := scheduler.New(queues, cCache, mgr.GetClient(), mgr.GetEventRecorderFor(constants.AdmissionName))
+	err = sched.Start(ctx)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+}
+
+func managerAndMultiKueueSetup(
+	ctx context.Context,
+	mgr manager.Manager,
+	gcInterval time.Duration,
+	enabledIntegrations sets.Set[string],
+	dispatcherName string,
+) {
+	managerSetup(ctx, mgr)
+
+	err := multikueue.SetupIndexer(ctx, mgr.GetFieldIndexer(), managersConfigNamespace.Name)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	adapters, err := jobframework.GetMultiKueueAdapters(enabledIntegrations)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	err = multikueue.SetupControllers(mgr, managersConfigNamespace.Name,
+		multikueue.WithGCInterval(gcInterval),
+		multikueue.WithWorkerLostTimeout(testingWorkerLostTimeout),
+		multikueue.WithEventsBatchPeriod(100*time.Millisecond),
+		multikueue.WithAdapters(adapters),
+		multikueue.WithDispatcherName(dispatcherName),
+	)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+}
+
+var _ = ginkgo.BeforeSuite(func() {
+	var managerFeatureGates []string
+	ginkgo.By("creating the clusters", func() {
+		mu = sync.Mutex{}
+		wg := sync.WaitGroup{}
+		wg.Add(3)
+		go func() {
+			defer ginkgo.GinkgoRecover()
+			defer wg.Done()
+			// pass nil setup since the manager for the manage cluster is different in some specs.
+			c := createCluster(nil, managerFeatureGates...)
+			managerTestCluster = c
+		}()
+		go func() {
+			defer ginkgo.GinkgoRecover()
+			defer wg.Done()
+			c := createCluster(managerSetup)
+			worker1TestCluster = c
+		}()
+		go func() {
+			defer ginkgo.GinkgoRecover()
+			defer wg.Done()
+			c := createCluster(managerSetup)
+			worker2TestCluster = c
+		}()
+		wg.Wait()
+	})
+
+	discoveryClient, err := discovery.NewDiscoveryClientForConfig(managerTestCluster.cfg)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+	managerK8sVersion, err = kubeversion.FetchServerVersion(discoveryClient)
+	gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+	managersConfigNamespace = utiltesting.MakeNamespace("kueue-system")
+	util.MustCreate(managerTestCluster.ctx, managerTestCluster.client, managersConfigNamespace)
+})
+
+var _ = ginkgo.AfterSuite(func() {
+	managerTestCluster.fwk.Teardown()
+	worker1TestCluster.fwk.Teardown()
+	worker2TestCluster.fwk.Teardown()
+})
diff --git a/test/integration/multikueue/tas/tas_test.go b/test/integration/multikueue/tas/tas_test.go
new file mode 100644
index 000000000..e3a3baa47
--- /dev/null
+++ b/test/integration/multikueue/tas/tas_test.go
@@ -0,0 +1,606 @@
+/*
+Copyright The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package multikueue
+
+import (
+	"context"
+	"time"
+
+	"github.com/google/go-cmp/cmp/cmpopts"
+	"github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
+	batchv1 "k8s.io/api/batch/v1"
+	corev1 "k8s.io/api/core/v1"
+	apimeta "k8s.io/apimachinery/pkg/api/meta"
+	"k8s.io/apimachinery/pkg/api/resource"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/apimachinery/pkg/util/sets"
+	autoscaling "k8s.io/autoscaler/cluster-autoscaler/apis/provisioningrequest/autoscaling.x-k8s.io/v1"
+	"k8s.io/utils/ptr"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/manager"
+
+	config "sigs.k8s.io/kueue/apis/config/v1beta2"
+	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
+	"sigs.k8s.io/kueue/pkg/controller/admissionchecks/provisioning"
+	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
+	"sigs.k8s.io/kueue/pkg/features"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
+	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
+	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
+	testingnode "sigs.k8s.io/kueue/pkg/util/testingjobs/node"
+	"sigs.k8s.io/kueue/test/util"
+)
+
+var defaultEnabledIntegrations sets.Set[string] = sets.New(
+	"batch/job", "kubeflow.org/mpijob", "ray.io/rayjob", "ray.io/raycluster",
+	"jobset.x-k8s.io/jobset", "kubeflow.org/paddlejob",
+	"kubeflow.org/pytorchjob", "kubeflow.org/tfjob", "kubeflow.org/xgboostjob", "kubeflow.org/jaxjob",
+	"pod", "workload.codeflare.dev/appwrapper")
+
+var _ = ginkgo.Describe("Topology Aware Scheduling", ginkgo.Ordered, func() {
+	var (
+		managerNs *corev1.Namespace
+		worker1Ns *corev1.Namespace
+		worker2Ns *corev1.Namespace
+
+		managerMultiKueueSecret1 *corev1.Secret
+		managerMultiKueueSecret2 *corev1.Secret
+		workerCluster1           *kueue.MultiKueueCluster
+		workerCluster2           *kueue.MultiKueueCluster
+		managerMultiKueueConfig  *kueue.MultiKueueConfig
+		multiKueueAC             *kueue.AdmissionCheck
+
+		managerTopology *kueue.Topology
+		worker1Topology *kueue.Topology
+		worker2Topology *kueue.Topology
+
+		managerTasFlavor *kueue.ResourceFlavor
+		worker1TasFlavor *kueue.ResourceFlavor
+		worker2TasFlavor *kueue.ResourceFlavor
+
+		managerCq *kueue.ClusterQueue
+		worker1Cq *kueue.ClusterQueue
+		worker2Cq *kueue.ClusterQueue
+
+		managerLq *kueue.LocalQueue
+		worker1Lq *kueue.LocalQueue
+		worker2Lq *kueue.LocalQueue
+
+		worker1Ac *kueue.AdmissionCheck
+		worker2Ac *kueue.AdmissionCheck
+
+		worker1Nodes []corev1.Node
+		worker2Nodes []corev1.Node
+	)
+
+	ginkgo.BeforeAll(func() {
+		managerTestCluster.fwk.StartManager(managerTestCluster.ctx, managerTestCluster.cfg, func(ctx context.Context, mgr manager.Manager) {
+			managerAndMultiKueueSetup(ctx, mgr, 2*time.Second, defaultEnabledIntegrations, config.MultiKueueDispatcherModeAllAtOnce)
+		})
+	})
+
+	ginkgo.AfterAll(func() {
+		managerTestCluster.fwk.StopManager(managerTestCluster.ctx)
+	})
+
+	ginkgo.BeforeEach(func() {
+		managerNs = util.CreateNamespaceFromPrefixWithLog(managerTestCluster.ctx, managerTestCluster.client, "multikueue-")
+		worker1Ns = util.CreateNamespaceWithLog(worker1TestCluster.ctx, worker1TestCluster.client, managerNs.Name)
+		worker2Ns = util.CreateNamespaceWithLog(worker2TestCluster.ctx, worker2TestCluster.client, managerNs.Name)
+
+		w1Kubeconfig, err := worker1TestCluster.kubeConfigBytes()
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+		w2Kubeconfig, err := worker2TestCluster.kubeConfigBytes()
+		gomega.Expect(err).NotTo(gomega.HaveOccurred())
+
+		managerMultiKueueSecret1 = &corev1.Secret{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "multikueue1",
+				Namespace: managersConfigNamespace.Name,
+			},
+			Data: map[string][]byte{
+				kueue.MultiKueueConfigSecretKey: w1Kubeconfig,
+			},
+		}
+		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerMultiKueueSecret1)).To(gomega.Succeed())
+
+		managerMultiKueueSecret2 = &corev1.Secret{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:      "multikueue2",
+				Namespace: managersConfigNamespace.Name,
+			},
+			Data: map[string][]byte{
+				kueue.MultiKueueConfigSecretKey: w2Kubeconfig,
+			},
+		}
+		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerMultiKueueSecret2)).To(gomega.Succeed())
+
+		workerCluster1 = utiltestingapi.MakeMultiKueueCluster("worker1").KubeConfig(kueue.SecretLocationType, managerMultiKueueSecret1.Name).Obj()
+		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, workerCluster1)).To(gomega.Succeed())
+
+		workerCluster2 = utiltestingapi.MakeMultiKueueCluster("worker2").KubeConfig(kueue.SecretLocationType, managerMultiKueueSecret2.Name).Obj()
+		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, workerCluster2)).To(gomega.Succeed())
+
+		managerMultiKueueConfig = utiltestingapi.MakeMultiKueueConfig("multikueueconfig").Clusters(workerCluster1.Name, workerCluster2.Name).Obj()
+		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerMultiKueueConfig)).Should(gomega.Succeed())
+
+		multiKueueAC = utiltestingapi.MakeAdmissionCheck("ac1").
+			ControllerName(kueue.MultiKueueControllerName).
+			Parameters(kueue.GroupVersion.Group, "MultiKueueConfig", managerMultiKueueConfig.Name).
+			Obj()
+		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, multiKueueAC)).Should(gomega.Succeed())
+
+		ginkgo.By("wait for check active", func() {
+			updatedAc := kueue.AdmissionCheck{}
+			acKey := client.ObjectKeyFromObject(multiKueueAC)
+			gomega.Eventually(func(g gomega.Gomega) {
+				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, acKey, &updatedAc)).To(gomega.Succeed())
+				g.Expect(updatedAc.Status.Conditions).To(utiltesting.HaveConditionStatusTrue(kueue.AdmissionCheckActive))
+			}, util.Timeout, util.Interval).Should(gomega.Succeed())
+		})
+
+		managerTopology = utiltestingapi.MakeDefaultOneLevelTopology("default")
+		util.MustCreate(managerTestCluster.ctx, managerTestCluster.client, managerTopology)
+
+		managerTasFlavor = utiltestingapi.MakeResourceFlavor("tas-flavor").
+			NodeLabel("node-group", "tas").
+			TopologyName(managerTopology.Name).Obj()
+		util.MustCreate(managerTestCluster.ctx, managerTestCluster.client, managerTasFlavor)
+
+		worker1Topology = utiltestingapi.MakeDefaultOneLevelTopology("default")
+		util.MustCreate(worker1TestCluster.ctx, worker1TestCluster.client, worker1Topology)
+
+		worker1TasFlavor = utiltestingapi.MakeResourceFlavor("tas-flavor").
+			NodeLabel("node-group", "tas").
+			TopologyName(worker1Topology.Name).Obj()
+		util.MustCreate(worker1TestCluster.ctx, worker1TestCluster.client, worker1TasFlavor)
+
+		worker2Topology = utiltestingapi.MakeDefaultOneLevelTopology("default")
+		util.MustCreate(worker2TestCluster.ctx, worker2TestCluster.client, worker2Topology)
+
+		worker2TasFlavor = utiltestingapi.MakeResourceFlavor("tas-flavor").
+			NodeLabel("node-group", "tas").
+			TopologyName(worker2Topology.Name).Obj()
+		util.MustCreate(worker2TestCluster.ctx, worker2TestCluster.client, worker2TasFlavor)
+	})
+
+	ginkgo.AfterEach(func() {
+		gomega.Expect(util.DeleteNamespace(managerTestCluster.ctx, managerTestCluster.client, managerNs)).To(gomega.Succeed())
+		gomega.Expect(util.DeleteNamespace(worker1TestCluster.ctx, worker1TestCluster.client, worker1Ns)).To(gomega.Succeed())
+		gomega.Expect(util.DeleteNamespace(worker2TestCluster.ctx, worker2TestCluster.client, worker2Ns)).To(gomega.Succeed())
+
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerLq, true)
+		util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, worker1Lq, true)
+		util.ExpectObjectToBeDeleted(worker2TestCluster.ctx, worker2TestCluster.client, worker2Lq, true)
+
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerCq, true)
+		util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, worker1Cq, true)
+		util.ExpectObjectToBeDeleted(worker2TestCluster.ctx, worker2TestCluster.client, worker2Cq, true)
+
+		util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, worker1Ac, true)
+		util.ExpectObjectToBeDeleted(worker2TestCluster.ctx, worker2TestCluster.client, worker2Ac, true)
+
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerTasFlavor, true)
+		util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, worker1TasFlavor, true)
+		util.ExpectObjectToBeDeleted(worker2TestCluster.ctx, worker2TestCluster.client, worker2TasFlavor, true)
+
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerTopology, true)
+		util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, worker1Topology, true)
+		util.ExpectObjectToBeDeleted(worker2TestCluster.ctx, worker2TestCluster.client, worker2Topology, true)
+
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, multiKueueAC, true)
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerMultiKueueConfig, true)
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, workerCluster1, true)
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, workerCluster2, true)
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerMultiKueueSecret1, true)
+		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerMultiKueueSecret2, true)
+	})
+
+	ginkgo.When("Topology has a single level", func() {
+		ginkgo.BeforeEach(func() {
+			managerCq = utiltestingapi.MakeClusterQueue("mgr-cluster-queue").
+				ResourceGroup(
+					*utiltestingapi.MakeFlavorQuotas(managerTasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
+				).
+				AdmissionChecks(kueue.AdmissionCheckReference(multiKueueAC.Name)).
+				Obj()
+			gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerCq)).Should(gomega.Succeed())
+			util.ExpectClusterQueuesToBeActive(managerTestCluster.ctx, managerTestCluster.client, managerCq)
+
+			managerLq = utiltestingapi.MakeLocalQueue("local-queue", managerNs.Name).ClusterQueue(managerCq.Name).Obj()
+			gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerLq)).Should(gomega.Succeed())
+
+			worker1Cq = utiltestingapi.MakeClusterQueue("wr-cluster-queue").
+				ResourceGroup(
+					*utiltestingapi.MakeFlavorQuotas(worker1TasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
+				).
+				Obj()
+			gomega.Expect(worker1TestCluster.client.Create(worker1TestCluster.ctx, worker1Cq)).Should(gomega.Succeed())
+			util.ExpectClusterQueuesToBeActive(worker1TestCluster.ctx, worker1TestCluster.client, worker1Cq)
+
+			worker1Lq = utiltestingapi.MakeLocalQueue("local-queue", worker1Ns.Name).ClusterQueue(worker1Cq.Name).Obj()
+			gomega.Expect(worker1TestCluster.client.Create(worker1TestCluster.ctx, worker1Lq)).Should(gomega.Succeed())
+
+			worker2Cq = utiltestingapi.MakeClusterQueue("cluster-queue").
+				ResourceGroup(
+					*utiltestingapi.MakeFlavorQuotas(worker2TasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
+				).
+				Obj()
+			gomega.Expect(worker2TestCluster.client.Create(worker2TestCluster.ctx, worker2Cq)).Should(gomega.Succeed())
+			util.ExpectClusterQueuesToBeActive(worker2TestCluster.ctx, worker2TestCluster.client, worker2Cq)
+
+			worker2Lq = utiltestingapi.MakeLocalQueue("local-queue", worker2Ns.Name).ClusterQueue(worker2Cq.Name).Obj()
+			gomega.Expect(worker2TestCluster.client.Create(worker2TestCluster.ctx, worker2Lq)).Should(gomega.Succeed())
+
+			worker1Nodes = []corev1.Node{
+				*testingnode.MakeNode("single-node").
+					Label(corev1.LabelHostname, "host-1").
+					Label("node-group", "tas").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:  resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+			}
+			worker2Nodes = []corev1.Node{
+				*testingnode.MakeNode("single-node").
+					Label(corev1.LabelHostname, "host-1").
+					Label("node-group", "tas").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:  resource.MustParse("5"),
+						corev1.ResourcePods: resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+			}
+			util.CreateNodesWithStatus(worker1TestCluster.ctx, worker1TestCluster.client, worker1Nodes)
+			util.CreateNodesWithStatus(worker2TestCluster.ctx, worker2TestCluster.client, worker2Nodes)
+		})
+
+		ginkgo.AfterEach(func() {
+			for _, node := range worker1Nodes {
+				util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, &node, true)
+			}
+			for _, node := range worker2Nodes {
+				util.ExpectObjectToBeDeleted(worker2TestCluster.ctx, worker2TestCluster.client, &node, true)
+			}
+		})
+
+		ginkgo.It("should admit workload which fits in a required topology domain", func() {
+			features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.MultiKueueBatchJobWithManagedBy, true)
+			features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.TopologyAwareScheduling, true)
+
+			job := testingjob.MakeJob("job", managerNs.Name).
+				ManagedBy(kueue.MultiKueueControllerName).
+				Queue(kueue.LocalQueueName(managerLq.Name)).
+				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, corev1.LabelHostname).
+				Request(corev1.ResourceCPU, "1").
+				Obj()
+			ginkgo.By("creating a job which requires block", func() {
+				util.MustCreate(managerTestCluster.ctx, managerTestCluster.client, job)
+			})
+
+			wl := &kueue.Workload{}
+			wlLookupKey := types.NamespacedName{Name: workloadjob.GetWorkloadNameForJob(job.Name, job.UID), Namespace: managerNs.Name}
+
+			ginkgo.By("verify the workload is created in manager cluster and has QuotaReserved", func() {
+				managerWl := &kueue.Workload{}
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, managerWl)).Should(gomega.Succeed())
+					g.Expect(apimeta.IsStatusConditionTrue(managerWl.Status.Conditions, kueue.WorkloadQuotaReserved)).Should(gomega.BeTrue())
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			var assignedWorkerCluster client.Client
+			var assignedWorkerCtx context.Context
+			var assignedClusterName string
+			ginkgo.By("checking which worker cluster was assigned", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					managerWl := &kueue.Workload{}
+					g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
+					g.Expect(managerWl.Status.ClusterName).NotTo(gomega.BeNil())
+
+					assignedClusterName = *managerWl.Status.ClusterName
+					g.Expect(assignedClusterName).To(gomega.Or(gomega.Equal(workerCluster1.Name), gomega.Equal(workerCluster2.Name)))
+					if assignedClusterName == workerCluster1.Name {
+						assignedWorkerCluster = worker1TestCluster.client
+						assignedWorkerCtx = worker1TestCluster.ctx
+					} else {
+						assignedWorkerCluster = worker2TestCluster.client
+						assignedWorkerCtx = worker2TestCluster.ctx
+					}
+
+					g.Expect(assignedWorkerCluster.Get(assignedWorkerCtx, wlLookupKey, wl)).To(gomega.Succeed())
+					g.Expect(wl.Spec.PodSets).Should(gomega.BeComparableTo([]kueue.PodSet{{
+						Name:  kueue.DefaultPodSetName,
+						Count: 1,
+						TopologyRequest: &kueue.PodSetTopologyRequest{
+							Required:      ptr.To(string(corev1.LabelHostname)),
+							PodIndexLabel: ptr.To(batchv1.JobCompletionIndexAnnotation),
+						},
+					}}, cmpopts.IgnoreFields(kueue.PodSet{}, "Template")))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("verify the workload is admitted in the assigned worker cluster", func() {
+				util.ExpectWorkloadsToBeAdmitted(assignedWorkerCtx, assignedWorkerCluster, wl)
+			})
+
+			ginkgo.By("verify TopologyAssignment for the workload in the assigned worker cluster", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(assignedWorkerCluster.Get(assignedWorkerCtx, wlLookupKey, wl)).Should(gomega.Succeed())
+					g.Expect(wl.Status.Admission).ShouldNot(gomega.BeNil())
+					g.Expect(wl.Status.Admission.PodSetAssignments).Should(gomega.HaveLen(1))
+					g.Expect(wl.Status.Admission.PodSetAssignments[0].TopologyAssignment).Should(gomega.BeComparableTo(
+						&kueue.TopologyAssignment{
+							Levels:  []string{corev1.LabelHostname},
+							Domains: []kueue.TopologyDomainAssignment{{Count: 1, Values: []string{"host-1"}}},
+						},
+					))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("verify DelayedTopologyRequest is marked Ready on manager", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					managerWl := &kueue.Workload{}
+					g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
+					g.Expect(managerWl.Status.Admission).NotTo(gomega.BeNil())
+					g.Expect(managerWl.Status.Admission.PodSetAssignments).To(gomega.HaveLen(1))
+					g.Expect(managerWl.Status.Admission.PodSetAssignments[0].DelayedTopologyRequest).To(gomega.Equal(ptr.To(kueue.DelayedTopologyRequestStateReady)))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
+
+	ginkgo.When("ProvisioningRequest is used", func() {
+		var (
+			worker1Prc *kueue.ProvisioningRequestConfig
+			worker2Prc *kueue.ProvisioningRequestConfig
+
+			createdRequest autoscaling.ProvisioningRequest
+		)
+
+		ginkgo.BeforeEach(func() {
+			worker1Prc = utiltestingapi.MakeProvisioningRequestConfig("prov-config").
+				ProvisioningClass("provisioning-class").
+				RetryLimit(1).
+				BaseBackoff(1).
+				PodSetUpdate(kueue.ProvisioningRequestPodSetUpdates{
+					NodeSelector: []kueue.ProvisioningRequestPodSetUpdatesNodeSelector{{
+						Key:                              "dedicated-selector-key",
+						ValueFromProvisioningClassDetail: "dedicated-selector-detail",
+					}},
+				}).
+				Obj()
+			util.MustCreate(worker1TestCluster.ctx, worker1TestCluster.client, worker1Prc)
+
+			worker2Prc = utiltestingapi.MakeProvisioningRequestConfig("prov-config").
+				ProvisioningClass("provisioning-class").
+				RetryLimit(1).
+				BaseBackoff(1).
+				PodSetUpdate(kueue.ProvisioningRequestPodSetUpdates{
+					NodeSelector: []kueue.ProvisioningRequestPodSetUpdatesNodeSelector{{
+						Key:                              "dedicated-selector-key",
+						ValueFromProvisioningClassDetail: "dedicated-selector-detail",
+					}},
+				}).
+				Obj()
+			util.MustCreate(worker2TestCluster.ctx, worker2TestCluster.client, worker2Prc)
+
+			worker1Ac = utiltestingapi.MakeAdmissionCheck("provisioning").
+				ControllerName(kueue.ProvisioningRequestControllerName).
+				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", worker1Prc.Name).
+				Obj()
+			util.MustCreate(worker1TestCluster.ctx, worker1TestCluster.client, worker1Ac)
+
+			worker2Ac = utiltestingapi.MakeAdmissionCheck("provisioning").
+				ControllerName(kueue.ProvisioningRequestControllerName).
+				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", worker2Prc.Name).
+				Obj()
+			util.MustCreate(worker2TestCluster.ctx, worker2TestCluster.client, worker2Ac)
+
+			util.SetAdmissionCheckActive(worker1TestCluster.ctx, worker1TestCluster.client, worker1Ac, metav1.ConditionTrue)
+			util.SetAdmissionCheckActive(worker2TestCluster.ctx, worker2TestCluster.client, worker2Ac, metav1.ConditionTrue)
+
+			managerCq = utiltestingapi.MakeClusterQueue("mgr-cluster-queue").
+				ResourceGroup(
+					*utiltestingapi.MakeFlavorQuotas(managerTasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
+				).
+				AdmissionChecks(kueue.AdmissionCheckReference(multiKueueAC.Name)).
+				Obj()
+			gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerCq)).Should(gomega.Succeed())
+			util.ExpectClusterQueuesToBeActive(managerTestCluster.ctx, managerTestCluster.client, managerCq)
+
+			managerLq = utiltestingapi.MakeLocalQueue("local-queue", managerNs.Name).ClusterQueue(managerCq.Name).Obj()
+			gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerLq)).Should(gomega.Succeed())
+
+			worker1Cq = utiltestingapi.MakeClusterQueue("wr-cluster-queue").
+				ResourceGroup(
+					*utiltestingapi.MakeFlavorQuotas(worker1TasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
+				).
+				AdmissionChecks(kueue.AdmissionCheckReference(worker1Ac.Name)).
+				Obj()
+			gomega.Expect(worker1TestCluster.client.Create(worker1TestCluster.ctx, worker1Cq)).Should(gomega.Succeed())
+			util.ExpectClusterQueuesToBeActive(worker1TestCluster.ctx, worker1TestCluster.client, worker1Cq)
+
+			worker1Lq = utiltestingapi.MakeLocalQueue("local-queue", worker1Ns.Name).ClusterQueue(worker1Cq.Name).Obj()
+			gomega.Expect(worker1TestCluster.client.Create(worker1TestCluster.ctx, worker1Lq)).Should(gomega.Succeed())
+
+			worker2Cq = utiltestingapi.MakeClusterQueue("cluster-queue").
+				ResourceGroup(
+					*utiltestingapi.MakeFlavorQuotas(worker2TasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
+				).
+				AdmissionChecks(kueue.AdmissionCheckReference(worker2Ac.Name)).
+				Obj()
+			gomega.Expect(worker2TestCluster.client.Create(worker2TestCluster.ctx, worker2Cq)).Should(gomega.Succeed())
+			util.ExpectClusterQueuesToBeActive(worker2TestCluster.ctx, worker2TestCluster.client, worker2Cq)
+
+			worker2Lq = utiltestingapi.MakeLocalQueue("local-queue", worker2Ns.Name).ClusterQueue(worker2Cq.Name).Obj()
+			gomega.Expect(worker2TestCluster.client.Create(worker2TestCluster.ctx, worker2Lq)).Should(gomega.Succeed())
+		})
+
+		ginkgo.AfterEach(func() {
+			util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, &createdRequest, true)
+
+			util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, worker1Prc, true)
+			util.ExpectObjectToBeDeleted(worker2TestCluster.ctx, worker2TestCluster.client, worker2Prc, true)
+
+			for _, node := range worker1Nodes {
+				util.ExpectObjectToBeDeleted(worker1TestCluster.ctx, worker1TestCluster.client, &node, true)
+			}
+			for _, node := range worker2Nodes {
+				util.ExpectObjectToBeDeleted(worker2TestCluster.ctx, worker2TestCluster.client, &node, true)
+			}
+		})
+
+		ginkgo.It("should admit workload when nodes are provisioned", func() {
+			features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.MultiKueueBatchJobWithManagedBy, true)
+			features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.TopologyAwareScheduling, true)
+
+			job := testingjob.MakeJob("job", managerNs.Name).
+				ManagedBy(kueue.MultiKueueControllerName).
+				Queue(kueue.LocalQueueName(managerLq.Name)).
+				PodAnnotation(kueue.PodSetRequiredTopologyAnnotation, corev1.LabelHostname).
+				Request(corev1.ResourceCPU, "1").
+				Obj()
+			ginkgo.By("creating a job which requires block", func() {
+				util.MustCreate(managerTestCluster.ctx, managerTestCluster.client, job)
+			})
+
+			wl := &kueue.Workload{}
+			wlLookupKey := types.NamespacedName{Name: workloadjob.GetWorkloadNameForJob(job.Name, job.UID), Namespace: managerNs.Name}
+
+			ginkgo.By("verify the workload reserves the quota", func() {
+				util.ExpectQuotaReservedWorkloadsTotalMetric(managerCq, "", 1)
+				util.ExpectReservingActiveWorkloadsMetric(managerCq, 1)
+			})
+
+			ginkgo.By("provision the nodes on both workers", func() {
+				worker1Nodes = []corev1.Node{
+					*testingnode.MakeNode("x1").
+						Label("node-group", "tas").
+						Label(corev1.LabelHostname, "x1").
+						StatusAllocatable(corev1.ResourceList{
+							corev1.ResourceCPU:    resource.MustParse("1"),
+							corev1.ResourceMemory: resource.MustParse("1Gi"),
+							corev1.ResourcePods:   resource.MustParse("10"),
+						}).
+						Ready().
+						Obj(),
+				}
+				worker2Nodes = []corev1.Node{
+					*testingnode.MakeNode("x1").
+						Label("node-group", "tas").
+						Label(corev1.LabelHostname, "x1").
+						StatusAllocatable(corev1.ResourceList{
+							corev1.ResourceCPU:    resource.MustParse("1"),
+							corev1.ResourceMemory: resource.MustParse("1Gi"),
+							corev1.ResourcePods:   resource.MustParse("10"),
+						}).
+						Ready().
+						Obj(),
+				}
+				util.CreateNodesWithStatus(worker1TestCluster.ctx, worker1TestCluster.client, worker1Nodes)
+				util.CreateNodesWithStatus(worker2TestCluster.ctx, worker2TestCluster.client, worker2Nodes)
+			})
+
+			var assignedWorkerCluster client.Client
+			var assignedWorkerCtx context.Context
+			var assignedClusterName string
+			var assignedAcName string
+			ginkgo.By("checking which worker cluster was assigned", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					managerWl := &kueue.Workload{}
+					g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
+					g.Expect(managerWl.Status.ClusterName).NotTo(gomega.BeNil())
+
+					assignedClusterName = *managerWl.Status.ClusterName
+					g.Expect(assignedClusterName).To(gomega.Or(gomega.Equal(workerCluster1.Name), gomega.Equal(workerCluster2.Name)))
+					if assignedClusterName == workerCluster1.Name {
+						assignedWorkerCluster = worker1TestCluster.client
+						assignedWorkerCtx = worker1TestCluster.ctx
+						assignedAcName = worker1Ac.Name
+					} else {
+						assignedWorkerCluster = worker2TestCluster.client
+						assignedWorkerCtx = worker2TestCluster.ctx
+						assignedAcName = worker2Ac.Name
+					}
+
+					g.Expect(assignedWorkerCluster.Get(assignedWorkerCtx, wlLookupKey, wl)).To(gomega.Succeed())
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			provReqKey := types.NamespacedName{
+				Namespace: wlLookupKey.Namespace,
+				Name:      provisioning.ProvisioningRequestName(wlLookupKey.Name, kueue.AdmissionCheckReference(assignedAcName), 1),
+			}
+
+			ginkgo.By("set the ProvisioningRequest as Provisioned in the assigned worker cluster", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(assignedWorkerCluster.Get(assignedWorkerCtx, provReqKey, &createdRequest)).Should(gomega.Succeed())
+					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
+						Type:   autoscaling.Provisioned,
+						Status: metav1.ConditionTrue,
+						Reason: autoscaling.Provisioned,
+					})
+					g.Expect(assignedWorkerCluster.Status().Update(assignedWorkerCtx, &createdRequest)).Should(gomega.Succeed())
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("verify the workload is admitted in the assigned worker cluster", func() {
+				util.ExpectWorkloadsToBeAdmitted(assignedWorkerCtx, assignedWorkerCluster, wl)
+			})
+
+			ginkgo.By("verify TopologyAssignment for the workload in the assigned worker cluster", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(assignedWorkerCluster.Get(assignedWorkerCtx, wlLookupKey, wl)).To(gomega.Succeed())
+					g.Expect(wl.Status.Admission).ShouldNot(gomega.BeNil())
+					g.Expect(wl.Status.Admission.PodSetAssignments).Should(gomega.HaveLen(1))
+					g.Expect(wl.Status.Admission.PodSetAssignments[0].TopologyAssignment).Should(gomega.BeComparableTo(
+						&kueue.TopologyAssignment{
+							Levels: []string{
+								corev1.LabelHostname,
+							},
+							Domains: []kueue.TopologyDomainAssignment{
+								{
+									Count: 1,
+									Values: []string{
+										"x1",
+									},
+								},
+							},
+						},
+					))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("verify DelayedTopologyRequest is marked Ready on manager", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					managerWl := &kueue.Workload{}
+					g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
+					g.Expect(managerWl.Status.Admission).NotTo(gomega.BeNil())
+					g.Expect(managerWl.Status.Admission.PodSetAssignments).To(gomega.HaveLen(1))
+					g.Expect(managerWl.Status.Admission.PodSetAssignments[0].DelayedTopologyRequest).To(gomega.Equal(ptr.To(kueue.DelayedTopologyRequestStateReady)))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
+})
diff --git a/test/integration/singlecluster/controller/core/workload_controller_test.go b/test/integration/singlecluster/controller/core/workload_controller_test.go
index e9efa7fa6..0f2f5be83 100644
--- a/test/integration/singlecluster/controller/core/workload_controller_test.go
+++ b/test/integration/singlecluster/controller/core/workload_controller_test.go
@@ -25,13 +25,11 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	apimeta "k8s.io/apimachinery/pkg/api/meta"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	config "sigs.k8s.io/kueue/apis/config/v1beta2"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/util/admissioncheck"
 	"sigs.k8s.io/kueue/pkg/util/slices"
@@ -52,7 +50,6 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 		clusterQueue                 *kueue.ClusterQueue
 		workloadPriorityClass        *kueue.WorkloadPriorityClass
 		updatedWorkloadPriorityClass *kueue.WorkloadPriorityClass
-		realClock                    = clock.RealClock{}
 	)
 
 	ginkgo.BeforeAll(func() {
@@ -227,12 +224,12 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 						Name:    "check1",
 						State:   kueue.CheckStateReady,
 						Message: "check successfully passed",
-					}, realClock)
+					}, util.RealClock)
 					workload.SetAdmissionCheckState(&createdWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:    "check2",
 						State:   kueue.CheckStateRetry,
 						Message: "check rejected",
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &createdWl)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -293,7 +290,7 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 						Name:    "check1",
 						State:   kueue.CheckStateRejected,
 						Message: "check rejected",
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &createdWl)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -345,12 +342,12 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 						Name:    "check1",
 						State:   kueue.CheckStateReady,
 						Message: "check ready",
-					}, realClock)
+					}, util.RealClock)
 					workload.SetAdmissionCheckState(&createdWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:    "check2",
 						State:   kueue.CheckStateReady,
 						Message: "check ready",
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &createdWl)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
@@ -374,7 +371,7 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 						Name:    "check1",
 						State:   kueue.CheckStateRejected,
 						Message: "check rejected",
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &createdWl)).To(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -416,7 +413,9 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 		ginkgo.It("case of WorkloadPriorityClass", func() {
 			ginkgo.By("creating workload")
 			wl = utiltestingapi.MakeWorkload("wl", ns.Name).Queue("lq").Request(corev1.ResourceCPU, "1").
-				PriorityClass("workload-priority-class").PriorityClassSource(constants.WorkloadPriorityClassSource).Priority(200).Obj()
+				WorkloadPriorityClassRef("workload-priority-class").
+				Priority(200).
+				Obj()
 			util.MustCreate(ctx, k8sClient, wl)
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedQueueWorkload)).To(gomega.Succeed())
@@ -506,8 +505,8 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 			ginkgo.By("evicting the workload, the accumulated admission time is updated", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, key, wl)).To(gomega.Succeed())
-					g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, wl, realClock, func() (*kueue.Workload, bool, error) {
-						return wl, workload.SetEvictedCondition(wl, realClock.Now(), "ByTest", "by test"), nil
+					g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, wl, util.RealClock, func() (*kueue.Workload, bool, error) {
+						return wl, workload.SetEvictedCondition(wl, util.RealClock.Now(), "ByTest", "by test"), nil
 					})).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 				util.FinishEvictionForWorkloads(ctx, k8sClient, wl)
diff --git a/test/integration/singlecluster/controller/jobs/appwrapper/appwrapper_controller_test.go b/test/integration/singlecluster/controller/jobs/appwrapper/appwrapper_controller_test.go
index 8ed59b7f9..2011b69ad 100644
--- a/test/integration/singlecluster/controller/jobs/appwrapper/appwrapper_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/appwrapper/appwrapper_controller_test.go
@@ -30,7 +30,6 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -57,8 +56,6 @@ const (
 )
 
 var _ = ginkgo.Describe("AppWrapper controller", ginkgo.Ordered, ginkgo.ContinueOnFailure, ginkgo.ContinueOnFailure, func() {
-	var realClock = clock.RealClock{}
-
 	ginkgo.BeforeAll(func() {
 		fwk.StartManager(ctx, cfg, managerSetup(jobframework.WithManageJobsWithoutQueueName(true),
 			jobframework.WithManagedJobsNamespaceSelector(util.NewNamespaceSelectorExcluding("unmanaged-ns"))))
@@ -285,7 +282,7 @@ var _ = ginkgo.Describe("AppWrapper controller", ginkgo.Ordered, ginkgo.Continue
 			ginkgo.By("preempt the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-					g.Expect(workload.UpdateStatus(ctx, k8sClient, createdWorkload, kueue.WorkloadEvicted, metav1.ConditionTrue, kueue.WorkloadEvictedByPreemption, "By test", "evict", clock.RealClock{})).To(gomega.Succeed())
+					g.Expect(workload.UpdateStatus(ctx, k8sClient, createdWorkload, kueue.WorkloadEvicted, metav1.ConditionTrue, kueue.WorkloadEvictedByPreemption, "By test", "evict", util.RealClock)).To(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -430,7 +427,7 @@ var _ = ginkgo.Describe("AppWrapper controller", ginkgo.Ordered, ginkgo.Continue
 								},
 							},
 						},
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &newWL)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
diff --git a/test/integration/singlecluster/controller/jobs/jaxjob/jaxjob_controller_test.go b/test/integration/singlecluster/controller/jobs/jaxjob/jaxjob_controller_test.go
index 3de5e2c52..ca5866111 100644
--- a/test/integration/singlecluster/controller/jobs/jaxjob/jaxjob_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/jaxjob/jaxjob_controller_test.go
@@ -25,7 +25,6 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -92,8 +91,6 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 })
 
 var _ = ginkgo.Describe("Job controller for workloads when only jobs with queue are managed", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() {
-	var realClock = clock.RealClock{}
-
 	ginkgo.BeforeAll(func() {
 		fwk.StartManager(ctx, cfg, managerSetup())
 	})
@@ -229,7 +226,7 @@ var _ = ginkgo.Describe("Job controller for workloads when only jobs with queue
 								},
 							},
 						},
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &newWL)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
diff --git a/test/integration/singlecluster/controller/jobs/job/job_controller_test.go b/test/integration/singlecluster/controller/jobs/job/job_controller_test.go
index 55e6ec827..c9c0097cd 100644
--- a/test/integration/singlecluster/controller/jobs/job/job_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/job/job_controller_test.go
@@ -35,7 +35,6 @@ import (
 	"k8s.io/apimachinery/pkg/selection"
 	"k8s.io/apimachinery/pkg/types"
 	utilfeature "k8s.io/apiserver/pkg/util/feature"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -68,8 +67,6 @@ const (
 )
 
 var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() {
-	var realClock = clock.RealClock{}
-
 	ginkgo.BeforeAll(func() {
 		fwk.StartManager(ctx, cfg, managerSetup(
 			jobframework.WithManageJobsWithoutQueueName(true),
@@ -639,7 +636,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 					kueue.WorkloadEvicted,
 					metav1.ConditionTrue,
 					kueue.WorkloadEvictedByPreemption, "By test", "evict",
-					clock.RealClock{},
+					util.RealClock,
 				)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
@@ -773,7 +770,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 								},
 							},
 						},
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &newWL)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -891,7 +888,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 								},
 							},
 						},
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &newWL)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -1397,8 +1394,6 @@ var _ = ginkgo.Describe("Interacting with scheduler", ginkgo.Ordered, ginkgo.Con
 			ginkgo.By("checking that the second workload is admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey2, createdWorkload2)).Should(gomega.Succeed())
-					g.Expect(createdWorkload2.Spec.PriorityClassName).Should(gomega.Equal(highWorkloadPriorityClass.Name))
-					g.Expect(*createdWorkload2.Spec.Priority).Should(gomega.Equal(highWorkloadPriorityClass.Value))
 					g.Expect(createdWorkload2.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -1498,8 +1493,6 @@ var _ = ginkgo.Describe("Interacting with scheduler", ginkgo.Ordered, ginkgo.Con
 			ginkgo.By("checking that the second workload is admitted", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey2, createdWorkload2)).Should(gomega.Succeed())
-					g.Expect(createdWorkload2.Spec.PriorityClassName).Should(gomega.Equal(highWorkloadPriorityClass.Name))
-					g.Expect(*createdWorkload2.Spec.Priority).Should(gomega.Equal(highWorkloadPriorityClass.Value))
 					g.Expect(createdWorkload2.Status.Conditions).Should(utiltesting.HaveConditionStatusTrue(kueue.WorkloadAdmitted))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -2405,7 +2398,7 @@ var _ = ginkgo.Describe("Interacting with scheduler", ginkgo.Ordered, ginkgo.Con
 					workload.SetAdmissionCheckState(&createdLowWorkload.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:  kueue.AdmissionCheckReference(admissionCheck.Name),
 						State: kueue.CheckStateReady,
-					}, clock.RealClock{})
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, createdLowWorkload)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -2451,7 +2444,7 @@ var _ = ginkgo.Describe("Interacting with scheduler", ginkgo.Ordered, ginkgo.Con
 					workload.SetAdmissionCheckState(&createdHighWorkload.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:  kueue.AdmissionCheckReference(admissionCheck.Name),
 						State: kueue.CheckStateReady,
-					}, clock.RealClock{})
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, createdHighWorkload)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
diff --git a/test/integration/singlecluster/controller/jobs/jobset/jobset_controller_test.go b/test/integration/singlecluster/controller/jobs/jobset/jobset_controller_test.go
index 251b06b0f..43b7d0550 100644
--- a/test/integration/singlecluster/controller/jobs/jobset/jobset_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/jobset/jobset_controller_test.go
@@ -28,7 +28,6 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -55,8 +54,6 @@ const (
 )
 
 var _ = ginkgo.Describe("JobSet controller", ginkgo.Ordered, ginkgo.ContinueOnFailure, ginkgo.ContinueOnFailure, func() {
-	var realClock = clock.RealClock{}
-
 	ginkgo.BeforeAll(func() {
 		fwk.StartManager(ctx, cfg, managerSetup(jobframework.WithManageJobsWithoutQueueName(true),
 			jobframework.WithManagedJobsNamespaceSelector(util.NewNamespaceSelectorExcluding("unmanaged-ns"))))
@@ -354,7 +351,7 @@ var _ = ginkgo.Describe("JobSet controller", ginkgo.Ordered, ginkgo.ContinueOnFa
 			ginkgo.By("preempt the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-					g.Expect(workload.UpdateStatus(ctx, k8sClient, createdWorkload, kueue.WorkloadEvicted, metav1.ConditionTrue, kueue.WorkloadEvictedByPreemption, "By test", "evict", clock.RealClock{})).To(gomega.Succeed())
+					g.Expect(workload.UpdateStatus(ctx, k8sClient, createdWorkload, kueue.WorkloadEvicted, metav1.ConditionTrue, kueue.WorkloadEvictedByPreemption, "By test", "evict", util.RealClock)).To(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -591,7 +588,7 @@ var _ = ginkgo.Describe("JobSet controller", ginkgo.Ordered, ginkgo.ContinueOnFa
 								},
 							},
 						},
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &newWL)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
diff --git a/test/integration/singlecluster/controller/jobs/mpijob/mpijob_controller_test.go b/test/integration/singlecluster/controller/jobs/mpijob/mpijob_controller_test.go
index 22af84fd5..7fd268284 100644
--- a/test/integration/singlecluster/controller/jobs/mpijob/mpijob_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/mpijob/mpijob_controller_test.go
@@ -28,7 +28,6 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -55,8 +54,6 @@ const (
 )
 
 var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailure, ginkgo.ContinueOnFailure, func() {
-	var realClock = clock.RealClock{}
-
 	ginkgo.BeforeAll(func() {
 		fwk.StartManager(ctx, cfg, managerSetup(false, jobframework.WithManageJobsWithoutQueueName(true),
 			jobframework.WithManagedJobsNamespaceSelector(util.NewNamespaceSelectorExcluding("unmanaged-ns"))))
@@ -369,7 +366,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 								},
 							},
 						},
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &newWL)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
diff --git a/test/integration/singlecluster/controller/jobs/pod/pod_controller_test.go b/test/integration/singlecluster/controller/jobs/pod/pod_controller_test.go
index d617e41fe..36f0ed51b 100644
--- a/test/integration/singlecluster/controller/jobs/pod/pod_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/pod/pod_controller_test.go
@@ -28,7 +28,6 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
@@ -61,8 +60,6 @@ var (
 )
 
 var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() {
-	var realClock = clock.RealClock{}
-
 	ginkgo.When("manageJobsWithoutQueueName is disabled", func() {
 		var defaultFlavor = utiltestingapi.MakeResourceFlavor("default").NodeLabel(corev1.LabelArchStable, "arm64").Obj()
 		var clusterQueue = utiltestingapi.MakeClusterQueue("cluster-queue").
@@ -331,7 +328,7 @@ var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 
 					gomega.Expect(
 						workload.UpdateStatus(ctx, k8sClient, createdWorkload, kueue.WorkloadEvicted, metav1.ConditionTrue,
-							kueue.WorkloadEvictedByPreemption, "By test", "evict", clock.RealClock{}),
+							kueue.WorkloadEvictedByPreemption, "By test", "evict", util.RealClock),
 					).Should(gomega.Succeed())
 					util.FinishEvictionForWorkloads(ctx, k8sClient, createdWorkload)
 
@@ -509,7 +506,7 @@ var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 										},
 									},
 								},
-							}, realClock)
+							}, util.RealClock)
 							g.Expect(k8sClient.Status().Update(ctx, &newWL)).Should(gomega.Succeed())
 						}, util.Timeout, util.Interval).Should(gomega.Succeed())
 					})
@@ -834,8 +831,8 @@ var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 					createdWorkload := &kueue.Workload{}
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
-						g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, createdWorkload, realClock, func() (*kueue.Workload, bool, error) {
-							return createdWorkload, workload.SetEvictedCondition(createdWorkload, realClock.Now(), "ByTest", "by test"), nil
+						g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, createdWorkload, util.RealClock, func() (*kueue.Workload, bool, error) {
+							return createdWorkload, workload.SetEvictedCondition(createdWorkload, util.RealClock.Now(), "ByTest", "by test"), nil
 						})).Should(gomega.Succeed())
 					}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
@@ -1427,8 +1424,8 @@ var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 				ginkgo.By("setting evicted condition to true", func() {
 					gomega.Eventually(func(g gomega.Gomega) {
 						g.Expect(k8sClient.Get(ctx, wlKey, wl)).Should(gomega.Succeed())
-						g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, wl, realClock, func() (*kueue.Workload, bool, error) {
-							return wl, workload.SetEvictedCondition(wl, realClock.Now(), kueue.WorkloadEvictedByPreemption, "By test"), nil
+						g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, wl, util.RealClock, func() (*kueue.Workload, bool, error) {
+							return wl, workload.SetEvictedCondition(wl, util.RealClock.Now(), kueue.WorkloadEvictedByPreemption, "By test"), nil
 						})).Should(gomega.Succeed())
 					}, util.Timeout, util.Interval).Should(gomega.Succeed())
 				})
diff --git a/test/integration/singlecluster/controller/jobs/pytorchjob/pytorchjob_controller_test.go b/test/integration/singlecluster/controller/jobs/pytorchjob/pytorchjob_controller_test.go
index d00a656ea..2cb35dedc 100644
--- a/test/integration/singlecluster/controller/jobs/pytorchjob/pytorchjob_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/pytorchjob/pytorchjob_controller_test.go
@@ -25,7 +25,6 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -96,8 +95,6 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 })
 
 var _ = ginkgo.Describe("Job controller for workloads when only jobs with queue are managed", ginkgo.Ordered, ginkgo.ContinueOnFailure, func() {
-	var realClock = clock.RealClock{}
-
 	ginkgo.BeforeAll(func() {
 		fwk.StartManager(ctx, cfg, managerSetup())
 	})
@@ -233,7 +230,7 @@ var _ = ginkgo.Describe("Job controller for workloads when only jobs with queue
 								},
 							},
 						},
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &newWL)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
diff --git a/test/integration/singlecluster/controller/jobs/trainjob/trainjob_controller_test.go b/test/integration/singlecluster/controller/jobs/trainjob/trainjob_controller_test.go
index db477799a..4f2c9a827 100644
--- a/test/integration/singlecluster/controller/jobs/trainjob/trainjob_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/trainjob/trainjob_controller_test.go
@@ -29,7 +29,6 @@ import (
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	jobsetapi "sigs.k8s.io/jobset/api/jobset/v1alpha2"
@@ -259,7 +258,7 @@ var _ = ginkgo.Describe("Trainjob controller", ginkgo.Ordered, ginkgo.ContinueOn
 			ginkgo.By("preempt the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-					g.Expect(workload.UpdateStatus(ctx, k8sClient, createdWorkload, kueue.WorkloadEvicted, metav1.ConditionTrue, kueue.WorkloadEvictedByPreemption, "By test", "evict", clock.RealClock{})).To(gomega.Succeed())
+					g.Expect(workload.UpdateStatus(ctx, k8sClient, createdWorkload, kueue.WorkloadEvicted, metav1.ConditionTrue, kueue.WorkloadEvictedByPreemption, "By test", "evict", util.RealClock)).To(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
diff --git a/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go b/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
index 01d0d9676..5dd9e20c1 100644
--- a/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
+++ b/test/integration/singlecluster/scheduler/fairsharing/fair_sharing_test.go
@@ -60,10 +60,12 @@ var _ = ginkgo.Describe("Scheduler", ginkgo.Ordered, ginkgo.ContinueOnFailure, f
 
 	var createQueue = func(cq *kueue.ClusterQueue) *kueue.ClusterQueue {
 		util.MustCreate(ctx, k8sClient, cq)
+		util.ExpectClusterQueuesToBeActive(ctx, k8sClient, cq)
 		cqs = append(cqs, cq)
 
 		lq := utiltestingapi.MakeLocalQueue(cq.Name, ns.Name).ClusterQueue(cq.Name).Obj()
 		util.MustCreate(ctx, k8sClient, lq)
+		util.ExpectLocalQueuesToBeActive(ctx, k8sClient, lq)
 		lqs = append(lqs, lq)
 		return cq
 	}
@@ -953,34 +955,35 @@ var _ = ginkgo.Describe("Scheduler", ginkgo.Ordered, ginkgo.ContinueOnFailure, f
 
 		ginkgo.It("sticky workload deleted, next workload can admit", func() {
 			ginkgo.By("Creating borrowing workloads in queue2")
-			createWorkload("cq2", "1")
-			createWorkload("cq2", "1")
+			createWorkloadWithPriority("cq2", "1", 0)
+			createWorkloadWithPriority("cq2", "1", 0)
 			util.ExpectAdmittedWorkloadsTotalMetric(cq2, "", 2)
 
-			ginkgo.By("Create inadmissible workload in queue1")
-			createWorkloadWithPriority("cq1", "4", 999)
-
-			ginkgo.By("Verify doesn't admit")
-			util.ExpectAdmittedWorkloadsTotalMetric(cq1, "", 0)
-
 			ginkgo.By("Create admissible workloads in queue1")
 			stickyWorkload := createWorkloadWithPriority("cq1", "3", 99)
 
+			ginkgo.By("Verify the workload is counted as pending active")
+			util.ExpectPendingWorkloadsMetric(cq1, 1, 0)
+
 			ginkgo.By("Another admissible workload in queue1")
 			createWorkloadWithPriority("cq1", "3", 0)
 
+			ginkgo.By("Validate pending workloads")
+			util.ExpectPendingWorkloadsMetric(cq1, 2, 0)
+
 			ginkgo.By("Delete sticky workload")
 			util.ExpectObjectToBeDeleted(ctx, k8sClient, stickyWorkload, true)
 
 			ginkgo.By("Validate pending workloads")
-			util.ExpectPendingWorkloadsMetric(cq1, 1, 1)
+			util.ExpectPendingWorkloadsMetric(cq1, 1, 0)
 
 			ginkgo.By("Complete preemption")
 			util.FinishEvictionOfWorkloadsInCQ(ctx, k8sClient, cq2, 2)
 
 			ginkgo.By("Expected Total Admitted Workloads and Weighted Share")
 			util.ExpectAdmittedWorkloadsTotalMetric(cq1, "", 1)
-			util.ExpectClusterQueueWeightedShareMetric(cq1, 0.0)
+			util.ExpectAdmittedWorkloadsTotalMetric(cq2, "", 2)
+			util.ExpectClusterQueueWeightedShareMetric(cq1, 1000)
 			util.ExpectClusterQueueWeightedShareMetric(cq2, 0.0)
 		})
 	})
diff --git a/test/integration/singlecluster/scheduler/podsready/scheduler_test.go b/test/integration/singlecluster/scheduler/podsready/scheduler_test.go
index 225ae0853..9ce02c2c7 100644
--- a/test/integration/singlecluster/scheduler/podsready/scheduler_test.go
+++ b/test/integration/singlecluster/scheduler/podsready/scheduler_test.go
@@ -26,7 +26,6 @@ import (
 	apimeta "k8s.io/apimachinery/pkg/api/meta"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
@@ -244,8 +243,6 @@ var _ = ginkgo.Describe("SchedulerWithWaitForPodsReady", func() {
 	})
 
 	var _ = ginkgo.Context("Short PodsReady timeout", func() {
-		var realClock = clock.RealClock{}
-
 		ginkgo.BeforeEach(func() {
 			podsReadyTimeout = util.ShortTimeout
 			requeueingBackoffLimitCount = ptr.To[int32](2)
@@ -332,7 +329,7 @@ var _ = ginkgo.Describe("SchedulerWithWaitForPodsReady", func() {
 				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(prodWl), prodWl)).Should(gomega.Succeed())
 				g.Expect(workload.IsActive(prodWl)).Should(gomega.BeFalse())
 				g.Expect(prodWl.Status.RequeueState).Should(gomega.BeNil())
-				g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, prodWl, realClock, func() (*kueue.Workload, bool, error) {
+				g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, prodWl, util.RealClock, func() (*kueue.Workload, bool, error) {
 					return prodWl, workload.SetRequeuedCondition(prodWl, kueue.WorkloadDeactivated, "by test", false), nil
 				})).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
diff --git a/test/integration/singlecluster/scheduler/workload_controller_test.go b/test/integration/singlecluster/scheduler/workload_controller_test.go
index dd3d2e888..a9c33fd8e 100644
--- a/test/integration/singlecluster/scheduler/workload_controller_test.go
+++ b/test/integration/singlecluster/scheduler/workload_controller_test.go
@@ -24,12 +24,11 @@ import (
 	nodev1 "k8s.io/api/node/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-	"k8s.io/utils/clock"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
 	"sigs.k8s.io/kueue/pkg/util/slices"
-	"sigs.k8s.io/kueue/pkg/util/testing"
+	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
 	"sigs.k8s.io/kueue/pkg/workload"
 	"sigs.k8s.io/kueue/test/integration/framework"
@@ -126,7 +125,6 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 		})
 
 		ginkgo.It("the workload should have appropriate AdditionalChecks added", framework.SlowSpec, func() {
-			var realClock = clock.RealClock{}
 			wl := utiltestingapi.MakeWorkload("wl", ns.Name).
 				Queue("queue").
 				Request(resourceGPU, "3").
@@ -168,12 +166,12 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 						Name:    "check1",
 						State:   kueue.CheckStateReady,
 						Message: "check successfully passed",
-					}, realClock)
+					}, util.RealClock)
 					workload.SetAdmissionCheckState(&updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckState{
 						Name:    "check3",
 						State:   kueue.CheckStateReady,
 						Message: "check successfully passed",
-					}, realClock)
+					}, util.RealClock)
 					g.Expect(k8sClient.Status().Update(ctx, &updatedWl)).Should(gomega.Succeed())
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
 					g.Expect(workload.IsAdmitted(&updatedWl)).Should(gomega.BeTrue(), "should have been admitted")
@@ -186,7 +184,7 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 		ginkgo.BeforeEach(func() {
 			util.MustCreate(ctx, k8sClient, onDemandFlavor)
 
-			runtimeClass = testing.MakeRuntimeClass("kata", "bar-handler").PodOverhead(resources).Obj()
+			runtimeClass = utiltesting.MakeRuntimeClass("kata", "bar-handler").PodOverhead(resources).Obj()
 			util.MustCreate(ctx, k8sClient, runtimeClass)
 			clusterQueue = utiltestingapi.MakeClusterQueue("clusterqueue").
 				ResourceGroup(*utiltestingapi.MakeFlavorQuotas(onDemandFlavor.Name).
@@ -295,7 +293,7 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 
 	ginkgo.When("LimitRanges are defined", func() {
 		ginkgo.BeforeEach(func() {
-			limitRange := testing.MakeLimitRange("limits", ns.Name).WithValue("DefaultRequest", corev1.ResourceCPU, "3").Obj()
+			limitRange := utiltesting.MakeLimitRange("limits", ns.Name).WithValue("DefaultRequest", corev1.ResourceCPU, "3").Obj()
 			util.MustCreate(ctx, k8sClient, limitRange)
 			util.MustCreate(ctx, k8sClient, onDemandFlavor)
 			clusterQueue = utiltestingapi.MakeClusterQueue("clusterqueue").
@@ -571,7 +569,7 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 
 	ginkgo.When("RuntimeClass is defined and change", func() {
 		ginkgo.BeforeEach(func() {
-			runtimeClass = testing.MakeRuntimeClass("kata", "bar-handler").
+			runtimeClass = utiltesting.MakeRuntimeClass("kata", "bar-handler").
 				PodOverhead(corev1.ResourceList{corev1.ResourceCPU: resource.MustParse("2")}).
 				Obj()
 			util.MustCreate(ctx, k8sClient, runtimeClass)
@@ -663,7 +661,7 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 	ginkgo.When("LimitRanges are defined and change", func() {
 		var limitRange *corev1.LimitRange
 		ginkgo.BeforeEach(func() {
-			limitRange = testing.MakeLimitRange("limits", ns.Name).WithValue("DefaultRequest", corev1.ResourceCPU, "3").Obj()
+			limitRange = utiltesting.MakeLimitRange("limits", ns.Name).WithValue("DefaultRequest", corev1.ResourceCPU, "3").Obj()
 			util.MustCreate(ctx, k8sClient, limitRange)
 			util.MustCreate(ctx, k8sClient, onDemandFlavor)
 			clusterQueue = utiltestingapi.MakeClusterQueue("clusterqueue").
@@ -749,7 +747,7 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 	ginkgo.When("a LimitRange event occurs near workload deletion time", func() {
 		var limitRange *corev1.LimitRange
 		ginkgo.BeforeEach(func() {
-			limitRange = testing.MakeLimitRange("limits", ns.Name).WithValue("DefaultRequest", corev1.ResourceCPU, "3").Obj()
+			limitRange = utiltesting.MakeLimitRange("limits", ns.Name).WithValue("DefaultRequest", corev1.ResourceCPU, "3").Obj()
 			util.MustCreate(ctx, k8sClient, limitRange)
 			util.MustCreate(ctx, k8sClient, onDemandFlavor)
 			clusterQueue = utiltestingapi.MakeClusterQueue("clusterqueue").
diff --git a/test/integration/singlecluster/tas/tas_test.go b/test/integration/singlecluster/tas/tas_test.go
index a3d8fd9d9..fd606fc8a 100644
--- a/test/integration/singlecluster/tas/tas_test.go
+++ b/test/integration/singlecluster/tas/tas_test.go
@@ -212,57 +212,6 @@ var _ = ginkgo.Describe("Topology Aware Scheduling", ginkgo.Ordered, func() {
 		})
 	})
 
-	ginkgo.When("Negative scenarios for ClusterQueue configuration", func() {
-		var (
-			topology       *kueue.Topology
-			tasFlavor      *kueue.ResourceFlavor
-			clusterQueue   *kueue.ClusterQueue
-			admissionCheck *kueue.AdmissionCheck
-		)
-
-		ginkgo.BeforeEach(func() {
-			topology = utiltestingapi.MakeDefaultTwoLevelTopology("default")
-			util.MustCreate(ctx, k8sClient, topology)
-
-			tasFlavor = utiltestingapi.MakeResourceFlavor("tas-flavor").
-				NodeLabel("node-group", "tas").
-				TopologyName("default").Obj()
-			util.MustCreate(ctx, k8sClient, tasFlavor)
-		})
-
-		ginkgo.AfterEach(func() {
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, clusterQueue, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, tasFlavor, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, topology, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, admissionCheck, true)
-		})
-
-		ginkgo.It("should mark TAS ClusterQueue as inactive if used with MultiKueue", func() {
-			admissionCheck = utiltestingapi.MakeAdmissionCheck("multikueue").ControllerName(kueue.MultiKueueControllerName).Obj()
-			util.MustCreate(ctx, k8sClient, admissionCheck)
-			util.SetAdmissionCheckActive(ctx, k8sClient, admissionCheck, metav1.ConditionTrue)
-
-			clusterQueue = utiltestingapi.MakeClusterQueue("cq").
-				ResourceGroup(
-					*utiltestingapi.MakeFlavorQuotas(tasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
-				).AdmissionChecks(kueue.AdmissionCheckReference(admissionCheck.Name)).Obj()
-			util.MustCreate(ctx, k8sClient, clusterQueue)
-
-			gomega.Eventually(func(g gomega.Gomega) {
-				var updatedCq kueue.ClusterQueue
-				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(clusterQueue), &updatedCq)).To(gomega.Succeed())
-				g.Expect(updatedCq.Status.Conditions).Should(gomega.BeComparableTo([]metav1.Condition{
-					{
-						Type:    kueue.ClusterQueueActive,
-						Status:  metav1.ConditionFalse,
-						Reason:  "NotSupportedWithTopologyAwareScheduling",
-						Message: `Can't admit new workloads: TAS is not supported with MultiKueue admission check.`,
-					},
-				}, util.IgnoreConditionTimestampsAndObservedGeneration))
-			}, util.Timeout, util.Interval).Should(gomega.Succeed())
-		})
-	})
-
 	ginkgo.When("Single TAS Resource Flavor", func() {
 		var (
 			tasFlavor    *kueue.ResourceFlavor
@@ -1498,7 +1447,176 @@ var _ = ginkgo.Describe("Topology Aware Scheduling", ginkgo.Ordered, func() {
 				})
 			})
 		})
+		ginkgo.When("TASBalancePlacement is enabled", func() {
+			var (
+				nodes []corev1.Node
+			)
+			ginkgo.BeforeEach(func() {
+				nodes = []corev1.Node{
+					*testingnode.MakeNode("x1").
+						Label("node-group", "tas").
+						Label(utiltesting.DefaultBlockTopologyLevel, "b1").
+						Label(utiltesting.DefaultRackTopologyLevel, "r1").
+						Label(corev1.LabelHostname, "x1").
+						StatusAllocatable(corev1.ResourceList{
+							"nvidia.com/gpu":      resource.MustParse("12"),
+							corev1.ResourceCPU:    resource.MustParse("1"),
+							corev1.ResourceMemory: resource.MustParse("1Gi"),
+							corev1.ResourcePods:   resource.MustParse("20"),
+						}).
+						Ready().
+						Obj(),
+					*testingnode.MakeNode("x2").
+						Label("node-group", "tas").
+						Label(utiltesting.DefaultBlockTopologyLevel, "b1").
+						Label(utiltesting.DefaultRackTopologyLevel, "r1").
+						Label(corev1.LabelHostname, "x2").
+						StatusAllocatable(corev1.ResourceList{
+							"nvidia.com/gpu":      resource.MustParse("12"),
+							corev1.ResourceCPU:    resource.MustParse("1"),
+							corev1.ResourceMemory: resource.MustParse("1Gi"),
+							corev1.ResourcePods:   resource.MustParse("20"),
+						}).
+						Ready().
+						Obj(),
+					*testingnode.MakeNode("x3").
+						Label("node-group", "tas").
+						Label(utiltesting.DefaultBlockTopologyLevel, "b1").
+						Label(utiltesting.DefaultRackTopologyLevel, "r2").
+						Label(corev1.LabelHostname, "x3").
+						StatusAllocatable(corev1.ResourceList{
+							"nvidia.com/gpu":      resource.MustParse("14"),
+							corev1.ResourceCPU:    resource.MustParse("1"),
+							corev1.ResourceMemory: resource.MustParse("1Gi"),
+							corev1.ResourcePods:   resource.MustParse("20"),
+						}).
+						Ready().
+						Obj(),
+					*testingnode.MakeNode("x4").
+						Label("node-group", "tas").
+						Label(utiltesting.DefaultBlockTopologyLevel, "b1").
+						Label(utiltesting.DefaultRackTopologyLevel, "r2").
+						Label(corev1.LabelHostname, "x4").
+						StatusAllocatable(corev1.ResourceList{
+							"nvidia.com/gpu":      resource.MustParse("6"),
+							corev1.ResourceCPU:    resource.MustParse("1"),
+							corev1.ResourceMemory: resource.MustParse("1Gi"),
+							corev1.ResourcePods:   resource.MustParse("20"),
+						}).
+						Ready().
+						Obj(),
+				}
+				util.CreateNodesWithStatus(ctx, k8sClient, nodes)
+
+				topology = utiltestingapi.MakeDefaultThreeLevelTopology("default")
+				util.MustCreate(ctx, k8sClient, topology)
+
+				tasFlavor = utiltestingapi.MakeResourceFlavor("tas-flavor").
+					NodeLabel("node-group", "tas").
+					TopologyName("default").Obj()
+				util.MustCreate(ctx, k8sClient, tasFlavor)
+
+				clusterQueue = utiltestingapi.MakeClusterQueue("cluster-queue").
+					ResourceGroup(*utiltestingapi.MakeFlavorQuotas(tasFlavor.Name).Resource("nvidia.com/gpu", "40").Obj()).
+					Obj()
+				util.MustCreate(ctx, k8sClient, clusterQueue)
+				util.ExpectClusterQueuesToBeActive(ctx, k8sClient, clusterQueue)
+
+				localQueue = utiltestingapi.MakeLocalQueue("local-queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj()
+				util.MustCreate(ctx, k8sClient, localQueue)
 
+				_ = features.SetEnable(features.TASBalancedPlacement, true)
+			})
+
+			ginkgo.AfterEach(func() {
+				gomega.Expect(util.DeleteAllJobsInNamespace(ctx, k8sClient, ns)).Should(gomega.Succeed())
+				gomega.Expect(util.DeleteWorkloadsInNamespace(ctx, k8sClient, ns)).Should(gomega.Succeed())
+				gomega.Expect(util.DeleteObject(ctx, k8sClient, localQueue)).Should(gomega.Succeed())
+				util.ExpectObjectToBeDeleted(ctx, k8sClient, clusterQueue, true)
+				util.ExpectObjectToBeDeleted(ctx, k8sClient, tasFlavor, true)
+				util.ExpectObjectToBeDeleted(ctx, k8sClient, topology, true)
+				for _, node := range nodes {
+					util.ExpectObjectToBeDeleted(ctx, k8sClient, &node, true)
+				}
+
+				_ = features.SetEnable(features.TASBalancedPlacement, false)
+			})
+
+			ginkgo.It("place the workers evenly on selected nodes", func() {
+				var wl1 *kueue.Workload
+
+				ginkgo.By("creating a workload", func() {
+					wl1 = utiltestingapi.MakeWorkload("wl1", ns.Name).
+						PodSets(*utiltestingapi.MakePodSet("worker", 16).
+							PreferredTopologyRequest(utiltesting.DefaultRackTopologyLevel).
+							SliceRequiredTopologyRequest(corev1.LabelHostname).
+							SliceSizeTopologyRequest(4).
+							Obj()).
+						Queue(kueue.LocalQueueName(localQueue.Name)).Request("nvidia.com/gpu", "1").Obj()
+					util.MustCreate(ctx, k8sClient, wl1)
+				})
+
+				ginkgo.By("verify the workload is admitted", func() {
+					util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, wl1)
+					gomega.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl1), wl1)).To(gomega.Succeed())
+					gomega.Expect(wl1.Status.Admission.PodSetAssignments[0].TopologyAssignment).Should(gomega.BeComparableTo(
+						&kueue.TopologyAssignment{
+							Levels: []string{corev1.LabelHostname},
+							Domains: []kueue.TopologyDomainAssignment{
+								{Count: 8, Values: []string{"x1"}},
+								{Count: 8, Values: []string{"x2"}},
+							},
+						},
+					))
+				})
+			})
+			ginkgo.It("place the leader and workers evenly on selected nodes", func() {
+				var wl1 *kueue.Workload
+
+				ginkgo.By("creating a workload", func() {
+					wl1 = utiltestingapi.MakeWorkload("wl1", ns.Name).
+						PodSets(
+							*utiltestingapi.MakePodSet("leader", 1).
+								PodSetGroup("group").
+								PreferredTopologyRequest(utiltesting.DefaultRackTopologyLevel).
+								SliceRequiredTopologyRequest(corev1.LabelHostname).
+								Request("nvidia.com/gpu", "1").
+								Obj(),
+							*utiltestingapi.MakePodSet("worker", 30).
+								PodSetGroup("group").
+								PreferredTopologyRequest(utiltesting.DefaultRackTopologyLevel).
+								SliceRequiredTopologyRequest(corev1.LabelHostname).
+								SliceSizeTopologyRequest(5).
+								Request("nvidia.com/gpu", "1").
+								Obj()).
+						Queue(kueue.LocalQueueName(localQueue.Name)).Obj()
+					util.MustCreate(ctx, k8sClient, wl1)
+				})
+
+				ginkgo.By("verify the workload is admitted", func() {
+					util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, wl1)
+					gomega.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl1), wl1)).To(gomega.Succeed())
+					gomega.Expect(wl1.Status.Admission.PodSetAssignments[0].TopologyAssignment).Should(gomega.BeComparableTo(
+						&kueue.TopologyAssignment{
+							Levels: []string{corev1.LabelHostname},
+							Domains: []kueue.TopologyDomainAssignment{
+								{Count: 1, Values: []string{"x1"}},
+							},
+						},
+					))
+					gomega.Expect(wl1.Status.Admission.PodSetAssignments[1].TopologyAssignment).Should(gomega.BeComparableTo(
+						&kueue.TopologyAssignment{
+							Levels: []string{corev1.LabelHostname},
+							Domains: []kueue.TopologyDomainAssignment{
+								{Count: 10, Values: []string{"x1"}},
+								{Count: 10, Values: []string{"x2"}},
+								{Count: 10, Values: []string{"x3"}},
+							},
+						},
+					))
+				})
+			})
+		})
 		ginkgo.When("Preemption is enabled within ClusterQueue", func() {
 			var (
 				nodes []corev1.Node
diff --git a/test/integration/singlecluster/webhook/core/workload_test.go b/test/integration/singlecluster/webhook/core/workload_test.go
index 56904268e..86994368e 100644
--- a/test/integration/singlecluster/webhook/core/workload_test.go
+++ b/test/integration/singlecluster/webhook/core/workload_test.go
@@ -28,13 +28,11 @@ import (
 	schedulingv1 "k8s.io/api/scheduling/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/types"
-	"k8s.io/utils/clock"
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/features"
 	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	utiltestingapi "sigs.k8s.io/kueue/pkg/util/testing/v1beta2"
@@ -131,8 +129,6 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 		fwk.StopManager(ctx)
 	})
 
-	var realClock = clock.RealClock{}
-
 	ginkgo.Context("When creating a Workload", func() {
 		ginkgo.DescribeTable("Should have valid PodSet when creating", func(podSetsCapacity int, podSetCount int, isInvalid bool) {
 			podSets := make([]kueue.PodSet, podSetsCapacity)
@@ -171,23 +167,71 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 					).Obj()
 				},
 				utiltesting.BeInvalidError()),
-			ginkgo.Entry("invalid priorityClassName",
+			ginkgo.Entry("invalid priorityClassRef.name",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClass("invalid_class").
+						PodPriorityClassRef("invalid_class").
 						Priority(0).
 						Obj()
 				},
 				utiltesting.BeInvalidError()),
-			ginkgo.Entry("empty priorityClassName is valid",
+			ginkgo.Entry("invalid priorityClassRef.group",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						PriorityClassRef(&kueue.PriorityClassRef{
+							Group: "test",
+							Kind:  kueue.PodPriorityClassKind,
+							Name:  "low",
+						}).
+						Priority(100).
+						Obj()
+				},
+				utiltesting.BeInvalidError()),
+			ginkgo.Entry("invalid priorityClassRef.kind",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						PriorityClassRef(&kueue.PriorityClassRef{
+							Group: kueue.PodPriorityClassGroup,
+							Kind:  "test",
+							Name:  "low",
+						}).
+						Priority(100).
+						Obj()
+				},
+				utiltesting.BeInvalidError()),
+			ginkgo.Entry("incompatible priorityClassRef.kind (scheduling.k8s.io)",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						PriorityClassRef(&kueue.PriorityClassRef{
+							Group: kueue.PodPriorityClassGroup,
+							Kind:  kueue.WorkloadPriorityClassKind,
+							Name:  "low",
+						}).
+						Priority(100).
+						Obj()
+				},
+				utiltesting.BeInvalidError()),
+			ginkgo.Entry("incompatible priorityClassRef.kind (kueue.x-k8s.io)",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						PriorityClassRef(&kueue.PriorityClassRef{
+							Group: kueue.WorkloadPriorityClassGroup,
+							Kind:  kueue.PodPriorityClassKind,
+							Name:  "low",
+						}).
+						Priority(100).
+						Obj()
+				},
+				utiltesting.BeInvalidError()),
+			ginkgo.Entry("omitted priorityClassRef is valid",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).Priority(0).Obj()
 				},
 				gomega.Succeed()),
-			ginkgo.Entry("priority should not be nil when priorityClassName is set",
+			ginkgo.Entry("priority should not be nil when priorityClassRef is set",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClass("priority").
+						PodPriorityClassRef("priority").
 						Obj()
 				},
 				utiltesting.BeInvalidError()),
@@ -321,8 +365,8 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), wl)).To(gomega.Succeed())
-				err := workload.PatchAdmissionStatus(ctx, k8sClient, wl, clock.RealClock{}, func() (*kueue.Workload, bool, error) {
-					return wl, workload.SetQuotaReservation(wl, a, clock.RealClock{}), nil
+				err := workload.PatchAdmissionStatus(ctx, k8sClient, wl, util.RealClock, func() (*kueue.Workload, bool, error) {
+					return wl, workload.SetQuotaReservation(wl, a, util.RealClock), nil
 				})
 				g.Expect(err).Should(matcher)
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -369,6 +413,60 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 						Obj()).
 					Obj(),
 				utiltesting.BeForbiddenError()),
+			ginkgo.Entry("Pending delayedTopologyRequest",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						PodSets(
+							*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 3).
+								Request(corev1.ResourceCPU, "1").
+								Obj(),
+						).
+						Obj()
+				},
+				utiltestingapi.MakeAdmission("cluster-queue").
+					PodSets(utiltestingapi.MakePodSetAssignment(kueue.DefaultPodSetName).
+						Assignment(corev1.ResourceCPU, "flv", "3").
+						Count(3).
+						DelayedTopologyRequest(kueue.DelayedTopologyRequestStatePending).
+						Obj()).
+					Obj(),
+				gomega.Succeed()),
+			ginkgo.Entry("Ready delayedTopologyRequest",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						PodSets(
+							*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 3).
+								Request(corev1.ResourceCPU, "1").
+								Obj(),
+						).
+						Obj()
+				},
+				utiltestingapi.MakeAdmission("cluster-queue").
+					PodSets(utiltestingapi.MakePodSetAssignment(kueue.DefaultPodSetName).
+						Assignment(corev1.ResourceCPU, "flv", "3").
+						Count(3).
+						DelayedTopologyRequest(kueue.DelayedTopologyRequestStateReady).
+						Obj()).
+					Obj(),
+				gomega.Succeed()),
+			ginkgo.Entry("invalid delayedTopologyRequest",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						PodSets(
+							*utiltestingapi.MakePodSet(kueue.DefaultPodSetName, 3).
+								Request(corev1.ResourceCPU, "1").
+								Obj(),
+						).
+						Obj()
+				},
+				utiltestingapi.MakeAdmission("cluster-queue").
+					PodSets(utiltestingapi.MakePodSetAssignment(kueue.DefaultPodSetName).
+						Assignment(corev1.ResourceCPU, "flv", "3").
+						Count(3).
+						DelayedTopologyRequest("invalid").
+						Obj()).
+					Obj(),
+				utiltesting.BeInvalidError()),
 		)
 
 		ginkgo.DescribeTable("Should have valid values when setting AdmissionCheckState", func(w func() *kueue.Workload, acs kueue.AdmissionCheckState) {
@@ -377,7 +475,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), wl)).To(gomega.Succeed())
-				workload.SetAdmissionCheckState(&wl.Status.AdmissionChecks, acs, realClock)
+				workload.SetAdmissionCheckState(&wl.Status.AdmissionChecks, acs, util.RealClock)
 				g.Expect(k8sClient.Status().Update(ctx, wl)).Should(utiltesting.BeForbiddenError())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		},
@@ -587,34 +685,6 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 				},
 				gomega.Succeed(),
 			),
-			ginkgo.Entry("priorityClassSource should not be updated",
-				func() *kueue.Workload {
-					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						Queue("q").
-						PriorityClass("test-class").PriorityClassSource(constants.PodPriorityClassSource).
-						Priority(10).
-						Obj()
-				},
-				true,
-				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = constants.WorkloadPriorityClassSource
-				},
-				utiltesting.BeInvalidError(),
-			),
-			ginkgo.Entry("priorityClassName should not be updated",
-				func() *kueue.Workload {
-					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						Queue("q").
-						PriorityClass("test-class-1").PriorityClassSource(constants.PodPriorityClassSource).
-						Priority(10).
-						Obj()
-				},
-				true,
-				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassName = "test-class-2"
-				},
-				utiltesting.BeInvalidError(),
-			),
 			ginkgo.Entry("should change other fields of admissionchecks when podSetUpdates is immutable",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
@@ -643,32 +713,6 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 				},
 				gomega.Succeed(),
 			),
-			ginkgo.Entry("updating priorityClassName before setting reserve quota for workload",
-				func() *kueue.Workload {
-					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						Queue("q").
-						PriorityClass("test-class-1").PriorityClassSource(constants.PodPriorityClassSource).
-						Priority(10).Obj()
-				},
-				false,
-				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassName = "test-class-2"
-				},
-				gomega.Succeed(),
-			),
-			ginkgo.Entry("updating priorityClassSource before setting reserve quota for workload",
-				func() *kueue.Workload {
-					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						Queue("q").
-						PriorityClass("test-class").PriorityClassSource(constants.PodPriorityClassSource).
-						Priority(10).Obj()
-				},
-				false,
-				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = constants.WorkloadPriorityClassSource
-				},
-				gomega.Succeed(),
-			),
 			ginkgo.Entry("updating podSets before setting reserve quota for workload",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).Obj()
@@ -696,16 +740,6 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 				},
 				gomega.Succeed(),
 			),
-			ginkgo.Entry("Should allow the change of priority",
-				func() *kueue.Workload {
-					return utiltestingapi.MakeWorkload(workloadName, ns.Name).Obj()
-				},
-				false,
-				func(newWL *kueue.Workload) {
-					newWL.Spec.Priority = ptr.To[int32](10)
-				},
-				gomega.Succeed(),
-			),
 			ginkgo.Entry("Should forbid the change of spec.podSet",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).Obj()
@@ -793,14 +827,59 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 				},
 				utiltesting.BeInvalidError(),
 			),
-			ginkgo.Entry("can set workload priority class when QuotaReserved=false",
+			ginkgo.Entry("Should allow to change priority when QuotaReserved=false",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).Obj()
 				},
 				false,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = constants.WorkloadPriorityClassSource
-					newWL.Spec.PriorityClassName = "low"
+					newWL.Spec.Priority = ptr.To[int32](10)
+				},
+				gomega.Succeed(),
+			),
+			ginkgo.Entry("Should allow to change priority when QuotaReserved=true",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).Obj()
+				},
+				false,
+				func(newWL *kueue.Workload) {
+					newWL.Spec.Priority = ptr.To[int32](10)
+				},
+				gomega.Succeed(),
+			),
+			ginkgo.Entry("Should allow to change priority with priorityClassRef when QuotaReserved=false",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						Priority(0).
+						PodPriorityClassRef("low").
+						Obj()
+				},
+				false,
+				func(newWL *kueue.Workload) {
+					newWL.Spec.Priority = ptr.To[int32](10)
+				},
+				gomega.Succeed(),
+			),
+			ginkgo.Entry("Should allow to change priority with priorityClassRef when QuotaReserved=true",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
+						Priority(0).
+						PodPriorityClassRef("low").
+						Obj()
+				},
+				false,
+				func(newWL *kueue.Workload) {
+					newWL.Spec.Priority = ptr.To[int32](10)
+				},
+				gomega.Succeed(),
+			),
+			ginkgo.Entry("can set workload priorityClassRef when QuotaReserved=false",
+				func() *kueue.Workload {
+					return utiltestingapi.MakeWorkload(workloadName, ns.Name).Obj()
+				},
+				false,
+				func(newWL *kueue.Workload) {
+					newWL.Spec.PriorityClassRef = kueue.NewWorkloadPriorityClassRef("low")
 					newWL.Spec.Priority = ptr.To[int32](100)
 				},
 				gomega.Succeed(),
@@ -811,8 +890,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 				},
 				true,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = constants.WorkloadPriorityClassSource
-					newWL.Spec.PriorityClassName = "low"
+					newWL.Spec.PriorityClassRef = kueue.NewWorkloadPriorityClassRef("low")
 					newWL.Spec.Priority = ptr.To[int32](100)
 				},
 				utiltesting.BeInvalidError(),
@@ -820,14 +898,13 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 			ginkgo.Entry("can update workload priority class when QuotaReserved=false",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClassSource(constants.WorkloadPriorityClassSource).
-						PriorityClass("high").
+						WorkloadPriorityClassRef("high").
 						Priority(1000).
 						Obj()
 				},
 				false,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassName = "low"
+					newWL.Spec.PriorityClassRef.Name = "low"
 					newWL.Spec.Priority = ptr.To[int32](100)
 				},
 				gomega.Succeed(),
@@ -835,14 +912,13 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 			ginkgo.Entry("can update workload priority class when QuotaReserved=true",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClassSource(constants.WorkloadPriorityClassSource).
-						PriorityClass("high").
+						WorkloadPriorityClassRef("high").
 						Priority(1000).
 						Obj()
 				},
 				true,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassName = "low"
+					newWL.Spec.PriorityClassRef.Name = "low"
 					newWL.Spec.Priority = ptr.To[int32](100)
 				},
 				gomega.Succeed(),
@@ -850,15 +926,13 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 			ginkgo.Entry("can delete workload priority class when QuotaReserved=false",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClassSource(constants.WorkloadPriorityClassSource).
-						PriorityClass("high").
+						WorkloadPriorityClassRef("high").
 						Priority(1000).
 						Obj()
 				},
 				false,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = ""
-					newWL.Spec.PriorityClassName = ""
+					newWL.Spec.PriorityClassRef = nil
 					newWL.Spec.Priority = nil
 				},
 				gomega.Succeed(),
@@ -866,15 +940,13 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 			ginkgo.Entry("can't delete workload priority class when quota reserved when QuotaReserved=true",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClassSource(constants.WorkloadPriorityClassSource).
-						PriorityClass("high").
+						WorkloadPriorityClassRef("high").
 						Priority(1000).
 						Obj()
 				},
 				true,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = ""
-					newWL.Spec.PriorityClassName = ""
+					newWL.Spec.PriorityClassRef = nil
 					newWL.Spec.Priority = nil
 				},
 				utiltesting.BeInvalidError(),
@@ -885,8 +957,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 				},
 				false,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = constants.PodPriorityClassSource
-					newWL.Spec.PriorityClassName = "low"
+					newWL.Spec.PriorityClassRef = kueue.NewPodPriorityClassRef("low")
 					newWL.Spec.Priority = ptr.To[int32](100)
 				},
 				gomega.Succeed(),
@@ -897,8 +968,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 				},
 				true,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = constants.PodPriorityClassSource
-					newWL.Spec.PriorityClassName = "low"
+					newWL.Spec.PriorityClassRef = kueue.NewPodPriorityClassRef("low")
 					newWL.Spec.Priority = ptr.To[int32](100)
 				},
 				utiltesting.BeInvalidError(),
@@ -906,14 +976,13 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 			ginkgo.Entry("can update pod priority class when QuotaReserved=false",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClassSource(constants.PodPriorityClassSource).
-						PriorityClass("high").
+						PodPriorityClassRef("high").
 						Priority(1000).
 						Obj()
 				},
 				false,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassName = "low"
+					newWL.Spec.PriorityClassRef.Name = "low"
 					newWL.Spec.Priority = ptr.To[int32](100)
 				},
 				gomega.Succeed(),
@@ -921,14 +990,13 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 			ginkgo.Entry("can't update pod priority class when QuotaReserved=true",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClassSource(constants.PodPriorityClassSource).
-						PriorityClass("high").
+						PodPriorityClassRef("high").
 						Priority(1000).
 						Obj()
 				},
 				true,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassName = "low"
+					newWL.Spec.PriorityClassRef.Name = "low"
 					newWL.Spec.Priority = ptr.To[int32](100)
 				},
 				utiltesting.BeInvalidError(),
@@ -936,15 +1004,13 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 			ginkgo.Entry("can delete pod priority class when QuotaReserved=false",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClassSource(constants.PodPriorityClassSource).
-						PriorityClass("high").
+						PodPriorityClassRef("high").
 						Priority(1000).
 						Obj()
 				},
 				false,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = ""
-					newWL.Spec.PriorityClassName = ""
+					newWL.Spec.PriorityClassRef = nil
 					newWL.Spec.Priority = nil
 				},
 				gomega.Succeed(),
@@ -952,15 +1018,13 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 			ginkgo.Entry("can't delete pod priority class when QuotaReserved=true",
 				func() *kueue.Workload {
 					return utiltestingapi.MakeWorkload(workloadName, ns.Name).
-						PriorityClassSource(constants.PodPriorityClassSource).
-						PriorityClass("high").
+						PodPriorityClassRef("high").
 						Priority(1000).
 						Obj()
 				},
 				true,
 				func(newWL *kueue.Workload) {
-					newWL.Spec.PriorityClassSource = ""
-					newWL.Spec.PriorityClassName = ""
+					newWL.Spec.PriorityClassRef = nil
 					newWL.Spec.Priority = nil
 				},
 				utiltesting.BeInvalidError(),
@@ -1004,7 +1068,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 
 		ginkgo.It("Should have priority once priorityClassName is set", func() {
 			ginkgo.By("Creating a new Workload")
-			workload := utiltestingapi.MakeWorkload(workloadName, ns.Name).PriorityClass("priority").Obj()
+			workload := utiltestingapi.MakeWorkload(workloadName, ns.Name).PodPriorityClassRef("priority").Obj()
 			err := k8sClient.Create(ctx, workload)
 			gomega.Expect(err).Should(utiltesting.BeInvalidError())
 		})
@@ -1012,7 +1076,9 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 		ginkgo.It("workload's priority should be mutable when referencing WorkloadPriorityClass", func() {
 			ginkgo.By("creating workload")
 			wl := utiltestingapi.MakeWorkload("wl", ns.Name).Queue("lq").Request(corev1.ResourceCPU, "1").
-				PriorityClass("workload-priority-class").PriorityClassSource(constants.WorkloadPriorityClassSource).Priority(200).Obj()
+				WorkloadPriorityClassRef("workload-priority-class").
+				Priority(200).
+				Obj()
 			util.MustCreate(ctx, k8sClient, wl)
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedQueueWorkload)).To(gomega.Succeed())
@@ -1034,7 +1100,9 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 		ginkgo.It("workload's priority should be mutable when referencing PriorityClass", func() {
 			ginkgo.By("creating workload")
 			wl := utiltestingapi.MakeWorkload("wl", ns.Name).Queue("lq").Request(corev1.ResourceCPU, "1").
-				PriorityClass("priority-class").PriorityClassSource(constants.PodPriorityClassSource).Priority(100).Obj()
+				PodPriorityClassRef("priority-class").
+				Priority(100).
+				Obj()
 			util.MustCreate(ctx, k8sClient, wl)
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedQueueWorkload)).To(gomega.Succeed())
@@ -1143,7 +1211,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 					LastTransitionTime: metav1.NewTime(time.Now()),
 					PodSetUpdates:      []kueue.PodSetUpdate{{Name: "first", Labels: map[string]string{"foo": "bar"}}, {Name: "second"}},
 					State:              kueue.CheckStateReady,
-				}, realClock)
+				}, util.RealClock)
 				g.Expect(k8sClient.Status().Update(ctx, wl)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
@@ -1156,7 +1224,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 					LastTransitionTime: metav1.NewTime(time.Now()),
 					PodSetUpdates:      []kueue.PodSetUpdate{{Name: "first", Labels: map[string]string{"foo": "baz"}}, {Name: "second"}},
 					State:              kueue.CheckStateReady,
-				}, realClock)
+				}, util.RealClock)
 				g.Expect(k8sClient.Status().Update(ctx, wl)).Should(utiltesting.BeForbiddenError())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 		})
@@ -1180,7 +1248,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 						Assignment(corev1.ResourceCPU, "default", "1").
 						Obj()).
 					Obj()
-				workload.SetQuotaReservation(wl, admission, realClock)
+				workload.SetQuotaReservation(wl, admission, util.RealClock)
 				wl.Status.Admission = admission
 
 				g.Expect(k8sClient.Status().Update(ctx, wl)).Should(gomega.Succeed())
@@ -1213,7 +1281,7 @@ var _ = ginkgo.Describe("Workload validating webhook", ginkgo.Ordered, func() {
 						Count(10).
 						Obj()).
 					Obj()
-				workload.SetQuotaReservation(wl, admission, realClock)
+				workload.SetQuotaReservation(wl, admission, util.RealClock)
 				wl.Status.Admission = admission
 
 				g.Expect(k8sClient.Status().Update(ctx, wl)).Should(gomega.Succeed())
diff --git a/test/performance/scheduler/runner/controller/controller.go b/test/performance/scheduler/runner/controller/controller.go
index 4fefd877d..e8a4827a4 100644
--- a/test/performance/scheduler/runner/controller/controller.go
+++ b/test/performance/scheduler/runner/controller/controller.go
@@ -42,6 +42,7 @@ import (
 	"sigs.k8s.io/kueue/pkg/workload"
 	"sigs.k8s.io/kueue/test/performance/scheduler/runner/generator"
 	"sigs.k8s.io/kueue/test/performance/scheduler/runner/recorder"
+	"sigs.k8s.io/kueue/test/util"
 )
 
 type reconciler struct {
@@ -52,10 +53,6 @@ type reconciler struct {
 	clock         clock.Clock
 }
 
-var (
-	realClock = clock.RealClock{}
-)
-
 func (r *reconciler) getAdmittedTime(uid types.UID) (time.Time, bool) {
 	r.atLock.RLock()
 	defer r.atLock.RUnlock()
@@ -178,7 +175,7 @@ type options struct {
 type Option func(*options)
 
 var defaultOptions = options{
-	clock: realClock,
+	clock: util.RealClock,
 }
 
 func WithClock(_ testing.TB, c clock.Clock) Option {
diff --git a/test/util/constants.go b/test/util/constants.go
index f7519d9cf..889937604 100644
--- a/test/util/constants.go
+++ b/test/util/constants.go
@@ -24,6 +24,7 @@ import (
 	appsv1 "k8s.io/api/apps/v1"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/utils/clock"
 )
 
 const (
@@ -82,3 +83,5 @@ var (
 	// The agnhost container will print args passed and `exit 0`
 	BehaviorExitFast = []string{"entrypoint-tester"}
 )
+
+var RealClock = clock.RealClock{}
diff --git a/test/util/util.go b/test/util/util.go
index 68ab01fb0..68ac9828b 100644
--- a/test/util/util.go
+++ b/test/util/util.go
@@ -56,7 +56,6 @@ import (
 	"k8s.io/client-go/tools/remotecommand"
 	"k8s.io/component-base/metrics/testutil"
 	"k8s.io/klog/v2"
-	"k8s.io/utils/clock"
 	testingclock "k8s.io/utils/clock/testing"
 	"k8s.io/utils/ptr"
 	ctrl "sigs.k8s.io/controller-runtime"
@@ -67,7 +66,6 @@ import (
 	leaderworkersetv1 "sigs.k8s.io/lws/api/leaderworkerset/v1"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
-	"sigs.k8s.io/kueue/pkg/constants"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
 	"sigs.k8s.io/kueue/pkg/metrics"
 	"sigs.k8s.io/kueue/pkg/scheduler/preemption"
@@ -370,22 +368,24 @@ func expectWorkloadsToBeAdmittedCountWithOffset(ctx context.Context, offset int,
 
 func ExpectWorkloadsWithWorkloadPriority(ctx context.Context, c client.Client, name string, value int32, wlKeys ...client.ObjectKey) {
 	ginkgo.GinkgoHelper()
-	expectWorkloadsWithPriority(ctx, c, constants.WorkloadPriorityClassSource, name, value, wlKeys...)
+	expectWorkloadsWithPriority(ctx, c, kueue.WorkloadPriorityClassGroup, kueue.WorkloadPriorityClassKind, name, value, wlKeys...)
 }
 
 func ExpectWorkloadsWithPodPriority(ctx context.Context, c client.Client, name string, value int32, wlKeys ...client.ObjectKey) {
 	ginkgo.GinkgoHelper()
-	expectWorkloadsWithPriority(ctx, c, constants.PodPriorityClassSource, name, value, wlKeys...)
+	expectWorkloadsWithPriority(ctx, c, kueue.PodPriorityClassGroup, kueue.PodPriorityClassKind, name, value, wlKeys...)
 }
 
-func expectWorkloadsWithPriority(ctx context.Context, c client.Client, priorityClassSource, name string, value int32, wlKeys ...client.ObjectKey) {
+func expectWorkloadsWithPriority(ctx context.Context, c client.Client, priorityClassGroup kueue.PriorityClassGroup, priorityClassKind kueue.PriorityClassKind, name string, value int32, wlKeys ...client.ObjectKey) {
 	ginkgo.GinkgoHelper()
 	createdWl := &kueue.Workload{}
 	gomega.Eventually(func(g gomega.Gomega) {
 		for _, wlKey := range wlKeys {
 			g.Expect(c.Get(ctx, wlKey, createdWl)).To(gomega.Succeed())
-			g.Expect(createdWl.Spec.PriorityClassSource).To(gomega.Equal(priorityClassSource))
-			g.Expect(createdWl.Spec.PriorityClassName).To(gomega.Equal(name))
+			g.Expect(createdWl.Spec.PriorityClassRef).ToNot(gomega.BeNil())
+			g.Expect(createdWl.Spec.PriorityClassRef.Group).To(gomega.Equal(priorityClassGroup))
+			g.Expect(createdWl.Spec.PriorityClassRef.Kind).To(gomega.Equal(priorityClassKind))
+			g.Expect(createdWl.Spec.PriorityClassRef.Name).To(gomega.Equal(name))
 			g.Expect(createdWl.Spec.Priority).To(gomega.Equal(&value))
 		}
 	}, Timeout, Interval).Should(gomega.Succeed())
@@ -428,7 +428,7 @@ func SetRequeuedConditionWithPodsReadyTimeout(ctx context.Context, k8sClient cli
 	gomega.EventuallyWithOffset(1, func(g gomega.Gomega) {
 		var wl kueue.Workload
 		g.Expect(k8sClient.Get(ctx, wlKey, &wl)).Should(gomega.Succeed())
-		g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, &wl, clock.RealClock{}, func() (*kueue.Workload, bool, error) {
+		g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, &wl, RealClock, func() (*kueue.Workload, bool, error) {
 			return &wl, workload.SetRequeuedCondition(&wl, kueue.WorkloadEvictedByPodsReadyTimeout, fmt.Sprintf("Exceeded the PodsReady timeout %s", klog.KObj(&wl).String()), false), nil
 		})).Should(gomega.Succeed())
 	}, Timeout, Interval).Should(gomega.Succeed())
@@ -831,7 +831,7 @@ func SyncAdmittedConditionForWorkloads(ctx context.Context, k8sClient client.Cli
 	for _, wl := range wls {
 		gomega.EventuallyWithOffset(1, func(g gomega.Gomega) {
 			g.ExpectWithOffset(1, k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedWorkload)).To(gomega.Succeed())
-			g.ExpectWithOffset(1, workload.PatchAdmissionStatus(ctx, k8sClient, &updatedWorkload, clock.RealClock{}, func() (*kueue.Workload, bool, error) {
+			g.ExpectWithOffset(1, workload.PatchAdmissionStatus(ctx, k8sClient, &updatedWorkload, RealClock, func() (*kueue.Workload, bool, error) {
 				return &updatedWorkload, workload.SyncAdmittedCondition(&updatedWorkload, time.Now()), nil
 			})).To(gomega.Succeed())
 		}, Timeout, Interval).Should(gomega.Succeed())
@@ -857,7 +857,7 @@ func FinishEvictionForWorkloads(ctx context.Context, k8sClient client.Client, wl
 			var updatedWorkload kueue.Workload
 			g.Expect(k8sClient.Get(ctx, key, &updatedWorkload)).Should(gomega.Succeed())
 			if apimeta.IsStatusConditionTrue(updatedWorkload.Status.Conditions, kueue.WorkloadQuotaReserved) {
-				g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, &updatedWorkload, clock.RealClock{}, func() (*kueue.Workload, bool, error) {
+				g.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, &updatedWorkload, RealClock, func() (*kueue.Workload, bool, error) {
 					return &updatedWorkload, workload.UnsetQuotaReservationWithCondition(&updatedWorkload, "Pending", "By test", time.Now()), nil
 				}),
 				).Should(gomega.Succeed(), fmt.Sprintf("Unable to unset quota reservation for %q", key))
@@ -892,7 +892,7 @@ func SetWorkloadsAdmissionCheck(ctx context.Context, k8sClient client.Client, wl
 			workload.SetAdmissionCheckState(&updatedWorkload.Status.AdmissionChecks, kueue.AdmissionCheckState{
 				Name:  check,
 				State: state,
-			}, clock.RealClock{})
+			}, RealClock)
 		}
 		g.Expect(k8sClient.Status().Update(ctx, &updatedWorkload)).To(gomega.Succeed())
 	}, Timeout, Interval).Should(gomega.Succeed())
diff --git a/test/util/util_scheduling.go b/test/util/util_scheduling.go
index 3c6bc7f61..2ab6ea68b 100644
--- a/test/util/util_scheduling.go
+++ b/test/util/util_scheduling.go
@@ -24,7 +24,6 @@ import (
 	"k8s.io/apimachinery/pkg/api/meta"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/sets"
-	"k8s.io/utils/clock"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta2"
@@ -46,7 +45,6 @@ func FinishRunningWorkloadsInCQ(ctx context.Context, k8sClient client.Client, cq
 }
 
 func finishEvictionsOfAnyWorkloadsInCq(ctx context.Context, k8sClient client.Client, cq *kueue.ClusterQueue) sets.Set[types.UID] {
-	var realClock = clock.RealClock{}
 	finished := sets.New[types.UID]()
 	var wList kueue.WorkloadList
 	gomega.Expect(k8sClient.List(ctx, &wList)).To(gomega.Succeed())
@@ -57,7 +55,7 @@ func finishEvictionsOfAnyWorkloadsInCq(ctx context.Context, k8sClient client.Cli
 		evicted := meta.IsStatusConditionTrue(wl.Status.Conditions, kueue.WorkloadEvicted)
 		quotaReserved := meta.IsStatusConditionTrue(wl.Status.Conditions, kueue.WorkloadQuotaReserved)
 		if evicted && quotaReserved {
-			gomega.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, &wl, realClock, func() (*kueue.Workload, bool, error) {
+			gomega.Expect(workload.PatchAdmissionStatus(ctx, k8sClient, &wl, RealClock, func() (*kueue.Workload, bool, error) {
 				return &wl, workload.UnsetQuotaReservationWithCondition(&wl, "Pending", "Eviction finished by test", time.Now()), nil
 			}),
 			).To(gomega.Succeed())
diff --git a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go
index 9bb81ed2a..c9f19da97 100644
--- a/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go
+++ b/vendor/sigs.k8s.io/controller-runtime/pkg/envtest/server.go
@@ -109,7 +109,11 @@ var (
 // Environment creates a Kubernetes test environment that will start / stop the Kubernetes control plane and
 // install extension APIs.
 type Environment struct {
-	// ControlPlane is the ControlPlane including the apiserver and etcd
+	// ControlPlane is the ControlPlane including the apiserver and etcd.
+	// Binary paths (APIServer.Path, Etcd.Path, KubectlPath) can be pre-configured in ControlPlane.
+	// If DownloadBinaryAssets is true, the downloaded paths will always be used.
+	// If DownloadBinaryAssets is false and paths are not pre-configured (default is empty), they will be
+	// automatically resolved using BinaryAssetsDirectory.
 	ControlPlane controlplane.ControlPlane
 
 	// Scheme is used to determine if conversion webhooks should be enabled
@@ -211,6 +215,40 @@ func (te *Environment) Stop() error {
 	return te.ControlPlane.Stop()
 }
 
+// configureBinaryPaths configures the binary paths for the API server, etcd, and kubectl.
+// If DownloadBinaryAssets is true, it downloads and uses those paths.
+// If DownloadBinaryAssets is false, it only sets paths that are not already configured (empty).
+func (te *Environment) configureBinaryPaths() error {
+	apiServer := te.ControlPlane.GetAPIServer()
+
+	if te.ControlPlane.Etcd == nil {
+		te.ControlPlane.Etcd = &controlplane.Etcd{}
+	}
+
+	if te.DownloadBinaryAssets {
+		apiServerPath, etcdPath, kubectlPath, err := downloadBinaryAssets(context.TODO(),
+			te.BinaryAssetsDirectory, te.DownloadBinaryAssetsVersion, te.DownloadBinaryAssetsIndexURL)
+		if err != nil {
+			return err
+		}
+
+		apiServer.Path = apiServerPath
+		te.ControlPlane.Etcd.Path = etcdPath
+		te.ControlPlane.KubectlPath = kubectlPath
+	} else {
+		if apiServer.Path == "" {
+			apiServer.Path = process.BinPathFinder("kube-apiserver", te.BinaryAssetsDirectory)
+		}
+		if te.ControlPlane.Etcd.Path == "" {
+			te.ControlPlane.Etcd.Path = process.BinPathFinder("etcd", te.BinaryAssetsDirectory)
+		}
+		if te.ControlPlane.KubectlPath == "" {
+			te.ControlPlane.KubectlPath = process.BinPathFinder("kubectl", te.BinaryAssetsDirectory)
+		}
+	}
+	return nil
+}
+
 // Start starts a local Kubernetes server and updates te.ApiserverPort with the port it is listening on.
 func (te *Environment) Start() (*rest.Config, error) {
 	if te.useExistingCluster() {
@@ -229,10 +267,6 @@ func (te *Environment) Start() (*rest.Config, error) {
 	} else {
 		apiServer := te.ControlPlane.GetAPIServer()
 
-		if te.ControlPlane.Etcd == nil {
-			te.ControlPlane.Etcd = &controlplane.Etcd{}
-		}
-
 		if os.Getenv(envAttachOutput) == "true" {
 			te.AttachControlPlaneOutput = true
 		}
@@ -243,6 +277,9 @@ func (te *Environment) Start() (*rest.Config, error) {
 			if apiServer.Err == nil {
 				apiServer.Err = os.Stderr
 			}
+			if te.ControlPlane.Etcd == nil {
+				te.ControlPlane.Etcd = &controlplane.Etcd{}
+			}
 			if te.ControlPlane.Etcd.Out == nil {
 				te.ControlPlane.Etcd.Out = os.Stdout
 			}
@@ -251,20 +288,8 @@ func (te *Environment) Start() (*rest.Config, error) {
 			}
 		}
 
-		if te.DownloadBinaryAssets {
-			apiServerPath, etcdPath, kubectlPath, err := downloadBinaryAssets(context.TODO(),
-				te.BinaryAssetsDirectory, te.DownloadBinaryAssetsVersion, te.DownloadBinaryAssetsIndexURL)
-			if err != nil {
-				return nil, err
-			}
-
-			apiServer.Path = apiServerPath
-			te.ControlPlane.Etcd.Path = etcdPath
-			te.ControlPlane.KubectlPath = kubectlPath
-		} else {
-			apiServer.Path = process.BinPathFinder("kube-apiserver", te.BinaryAssetsDirectory)
-			te.ControlPlane.Etcd.Path = process.BinPathFinder("etcd", te.BinaryAssetsDirectory)
-			te.ControlPlane.KubectlPath = process.BinPathFinder("kubectl", te.BinaryAssetsDirectory)
+		if err := te.configureBinaryPaths(); err != nil {
+			return nil, fmt.Errorf("failed to configure binary paths: %w", err)
 		}
 
 		if err := te.defaultTimeouts(); err != nil {