Repository: kubernetes-sigs/kueue

Issue:
Flaky perf scheduling test
/kind flake

**What happened**:

https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/4845/pull-kueue-test-scheduling-perf-main/1906781402901254144

**What you expected to happen**:

no failures

**How to reproduce it (as minimally and precisely as possible)**:

ci

**Anything else we need to know?**:

```
{Failed  === RUN   TestScalability/CommandStats
    checker_test.go:87: Average CPU usage 538mCpu is greater than maximum expected 535mCPU
--- FAIL: TestScalability/CommandStats (0.00s)
}
```

Hints from issue comments:
@mimowo: 
This might be related to https://github.com/kubernetes-sigs/kueue/pull/4813 as it is using reclaimWithinCohort: Any. 

cc @mbobrovskyi ptal, maybe the cpu got higher recently, but the execution time dropped? If this is the case, I think it is WAI and I'm ok to bump the thresholds to make it stable.
@mimowo: Another occurrence: https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/4837/pull-kueue-test-scheduling-perf-main/1906685554880155648@mimowo: cc @gabesaba as this might be related to the recent scheduling changes@mimowo: another occurrence https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/4929/pull-kueue-test-scheduling-perf-main/1912139065210179584@mimowo: I would suggest to just bump the CPU to 550m. I don't like the CPU metric anyway and would be ok with dropping the threshold completely, as discussed before when introducing it. 

WDYT @tenzen-y @gabesaba @mbobrovskyi ?@mimowo: I would speculate the CPU consumption increased after the fix by @gabesaba of reclamation, and this is an expected change, but it is hard to confirm now@gabesaba: I would either: 

1) increase the threshold with the goal of replacing it very soon
2) delete it now

I lean towards option 2, and open a bug to track creating a better metric

> I don't like the CPU metric anyway and would be ok with dropping the threshold completely, as discussed before when introducing it.

+1


@mimowo: > I lean towards option 2, and open a bug to track creating a better metric

+1, but we already have [maxWallMs](https://github.com/kubernetes-sigs/kueue/blob/d68df3a996c1ef1f6dc4abeb156cc0f934141def/test/performance/scheduler/default_rangespec.yaml#L9) which is the total execution time. Do you have anything else on your mind?@tenzen-y: What metrics are used in kube-scheduler perf-test? Doesn't it use CPU threshold?
@mimowo: It currently does use [mCPU: 535](https://github.com/kubernetes-sigs/kueue/blob/d68df3a996c1ef1f6dc4abeb156cc0f934141def/test/performance/scheduler/default_rangespec.yaml#L12C3-L12C12), and this is the reason for the flakes, because occasionally this is exceeded as in this case it was 538mCpu.

Note that 535 is not the original value which was 500 (iirc), but later bumped. @tenzen-y: I meant kube-scheduler perf-test instead of kueue scheduler perf-test@mimowo: cc @macsko who is likely to know@macsko: > What metrics are used in kube-scheduler perf-test? Doesn't it use CPU threshold?

kube-scheduler perf tests ([scheduler_perf](https://github.com/kubernetes/kubernetes/tree/master/test/integration/scheduler_perf)) verify only the scheduling throughput, without checking cpu/memory usage. Code that calculates the throughput is [here](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L468-L615). It is done using [event handler subscribed on Pod/Add and Pod/Update events](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L486-L511). For statistical purposes, and not for calculating throughput itself, we use the [`scheduler_schedule_attempts_total` metric](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L597).@mimowo: > kube-scheduler perf tests ([scheduler_perf](https://github.com/kubernetes/kubernetes/tree/master/test/integration/scheduler_perf)) verify only the scheduling throughput, without checking cpu/memory usage.

So, I think we don't need it either.

> Code that calculates the throughput is [here](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L468-L615). It is done using [event handler subscribed on Pod/Add and Pod/Update events](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L486-L511). For statistical purposes, and not for calculating throughput itself, we use the [scheduler_schedule_attempts_total metric](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L597).

I would say that we also measure throughput in our tests, where ` maxWallMs` is a proxy, and more granual is `wlClassesMaxAvgTimeToAdmissionMs`. 

Probably we also don't need then cmd.maxrss and `clusterQueueClassesMinUsage` (though we haven't had flakes with them yet. WDYT @tenzen-y ? @tenzen-y: > > kube-scheduler perf tests ([scheduler_perf](https://github.com/kubernetes/kubernetes/tree/master/test/integration/scheduler_perf)) verify only the scheduling throughput, without checking cpu/memory usage.
> 
> So, I think we don't need it either.
> 
> > Code that calculates the throughput is [here](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L468-L615). It is done using [event handler subscribed on Pod/Add and Pod/Update events](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L486-L511). For statistical purposes, and not for calculating throughput itself, we use the [scheduler_schedule_attempts_total metric](https://github.com/kubernetes/kubernetes/blob/44c230bf5c321056e8bc89300b37c497f464f113/test/integration/scheduler_perf/util.go#L597).
> 
> I would say that we also measure throughput in our tests, where ` maxWallMs` is a proxy, and more granual is `wlClassesMaxAvgTimeToAdmissionMs`.
> 
> Probably we also don't need then cmd.maxrss and `clusterQueueClassesMinUsage` (though we haven't had flakes with them yet. WDYT [@tenzen-y](https://github.com/tenzen-y) ?

I synced with @mimowo offline. In conclusion, we agree with dropping the assertion based on the threshold for CPU and memory usage.
However, we keep collecting those metrics during CI and push the result to artifacts since those are still useful to evaluate Kueue project.
@IrvingMg: /assign@mimowo: new occurrence: https://prow.k8s.io/view/gs/kubernetes-ci-logs/pr-logs/pull/kubernetes-sigs_kueue/4989/pull-kueue-test-scheduling-perf-main/1915345602112131072

Solution patch:
diff --git a/Makefile b/Makefile
index 94500f336..898c9b89f 100644
--- a/Makefile
+++ b/Makefile
@@ -166,6 +166,11 @@ helm-verify: helm helm-lint ## run helm template and detect any rendering failur
 	$(HELM) template charts/kueue > /dev/null
 # test nondefault options (kueueviz, prometheus, certmanager)
 	$(HELM) template charts/kueue --set enableKueueViz=true --set enableCertManager=true --set enablePrometheus=true > /dev/null
+
+.PHONY: helm-unit-test
+helm-unit-test: helm
+	$(HELM) unittest charts/kueue --strict --debug
+
 .PHONY: vet
 vet: ## Run go vet against code.
 	$(GO_CMD) vet ./...
@@ -188,7 +193,7 @@ sync-hugo-version:
 
 PATHS_TO_VERIFY := config/components apis charts/kueue/templates client-go site/ netlify.toml
 .PHONY: verify
-verify: gomod-verify ci-lint fmt-verify shell-lint toc-verify manifests generate update-helm helm-verify prepare-release-branch sync-hugo-version
+verify: gomod-verify ci-lint fmt-verify shell-lint toc-verify manifests generate update-helm helm-verify helm-unit-test prepare-release-branch sync-hugo-version
 	git --no-pager diff --exit-code $(PATHS_TO_VERIFY)
 	if git ls-files --exclude-standard --others $(PATHS_TO_VERIFY) | grep -q . ; then exit 1; fi
 
@@ -282,7 +287,6 @@ artifacts: kustomize yq helm ## Generate release artifacts.
 	$(KUSTOMIZE) build config/dev -o artifacts/manifests-dev.yaml
 	$(KUSTOMIZE) build config/alpha-enabled -o artifacts/manifests-alpha-enabled.yaml
 	$(KUSTOMIZE) build config/prometheus -o artifacts/prometheus.yaml
-	$(KUSTOMIZE) build config/visibility-apf -o artifacts/visibility-apf.yaml
 	$(KUSTOMIZE) build config/kueueviz -o artifacts/kueueviz.yaml
 	@$(call clean-manifests)
 	# Update the image tag and policy
diff --git a/Makefile-deps.mk b/Makefile-deps.mk
index b5f3dd09e..da5454fc8 100644
--- a/Makefile-deps.mk
+++ b/Makefile-deps.mk
@@ -81,8 +81,11 @@ yq: ## Download yq locally if necessary.
 
 HELM = $(PROJECT_DIR)/bin/helm
 .PHONY: helm
-helm: ## Download helm locally if necessary.
+helm: ## Download helm and helm-unittest locally if necessary.
 	@GOBIN=$(PROJECT_DIR)/bin GO111MODULE=on $(GO_CMD) install helm.sh/helm/v3/cmd/helm@$(HELM_VERSION)
+	@if ! $(HELM) plugin list | grep -q unittest; then \
+		$(HELM) plugin install https://github.com/helm-unittest/helm-unittest.git; \
+	fi
 
 GENREF = $(PROJECT_DIR)/bin/genref
 .PHONY: genref
diff --git a/Makefile-test.mk b/Makefile-test.mk
index e88a0c87f..4d84b7fb2 100644
--- a/Makefile-test.mk
+++ b/Makefile-test.mk
@@ -100,7 +100,7 @@ test-integration: gomod-download envtest ginkgo dep-crds kueuectl ginkgo-top ##
 	$(PROJECT_DIR)/bin/ginkgo-top -i $(ARTIFACTS)/integration.json > $(ARTIFACTS)/integration-top.yaml
 
 .PHONY: test-multikueue-integration
-test-multikueue-integration: gomod-download envtest ginkgo dep-crds kueuectl ginkgo-top ## Run integration tests for Multikueue suite.
+test-multikueue-integration: gomod-download envtest ginkgo dep-crds ginkgo-top ## Run integration tests for MultiKueue suite.
 	KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" \
 	PROJECT_DIR=$(PROJECT_DIR)/ \
 	KUEUE_BIN=$(PROJECT_DIR)/bin \
@@ -127,11 +127,6 @@ test-e2e-customconfigs: kustomize ginkgo yq gomod-download dep-crds kueuectl gin
 .PHONY: test-e2e-certmanager
 test-e2e-certmanager: kustomize ginkgo yq gomod-download dep-crds kueuectl ginkgo-top run-test-e2e-certmanager-$(E2E_KIND_VERSION:kindest/node:v%=%)
 
-E2E_TARGETS := $(addprefix run-test-e2e-,${E2E_K8S_VERSIONS})
-MULTIKUEUE-E2E_TARGETS := $(addprefix run-test-multikueue-e2e-,${E2E_K8S_VERSIONS})
-.PHONY: test-e2e-all
-test-e2e-all: ginkgo ginkgo-top $(E2E_TARGETS) $(MULTIKUEUE-E2E_TARGETS)
-
 FORCE:
 
 run-test-e2e-singlecluster-%: K8S_VERSION = $(@:run-test-e2e-singlecluster-%=%)
diff --git a/README.md b/README.md
index d4420c898..e81ae8bc6 100644
--- a/README.md
+++ b/README.md
@@ -36,11 +36,16 @@ Read the [overview](https://kueue.sigs.k8s.io/docs/overview/) and watch the Kueu
 - ✔️ Test Coverage:
   - ✔️ Unit Test [testgrid](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-unit-main).
   - ✔️ 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.30](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-e2e-main-1-30),
     [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),
     on Kind.
+  - ✔️ E2E TAS Test [testgrid](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-e2e-tas-main)
+  - ✔️ E2E Custom Configs Test [testgrid](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-e2e-customconfigs-main)
+  - ✔️ E2E Cert Manager Test [testgrid](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-e2e-certmanager-main)
+  - ✔️ Performance Test [testgrid](https://testgrid.k8s.io/sig-scheduling#periodic-kueue-test-scheduling-perf-main)
 - ✔️ Scalability verification via [performance tests](https://github.com/kubernetes-sigs/kueue/tree/main/test/performance).
 - ✔️ Monitoring via [metrics](https://kueue.sigs.k8s.io/docs/reference/metrics).
 - ✔️ Security: RBAC based accessibility.
@@ -52,7 +57,7 @@ Read the [overview](https://kueue.sigs.k8s.io/docs/overview/) and watch the Kueu
 
 ## Installation
 
-**Requires Kubernetes 1.25 or newer**.
+**Requires Kubernetes 1.29 or newer**.
 
 To install the latest release of Kueue in your cluster, run the following command:
 
diff --git a/apis/config/v1beta1/defaults.go b/apis/config/v1beta1/defaults.go
index 89a3d4c4b..924bb6f28 100644
--- a/apis/config/v1beta1/defaults.go
+++ b/apis/config/v1beta1/defaults.go
@@ -160,7 +160,7 @@ func SetDefaults_Configuration(cfg *Configuration) {
 		}
 	}
 
-	if !features.Enabled((features.ManagedJobsNamespaceSelector)) {
+	if !features.Enabled(features.ManagedJobsNamespaceSelector) {
 		// Backwards compatibility: default podOptions.NamespaceSelector if ManagedJobsNamespaceSelector disabled
 		if cfg.Integrations.PodOptions == nil {
 			cfg.Integrations.PodOptions = &PodIntegrationOptions{}
diff --git a/apis/kueue/v1alpha1/tas_types.go b/apis/kueue/v1alpha1/topology_types.go
similarity index 99%
rename from apis/kueue/v1alpha1/tas_types.go
rename to apis/kueue/v1alpha1/topology_types.go
index 84ba98f03..a24fb02d8 100644
--- a/apis/kueue/v1alpha1/tas_types.go
+++ b/apis/kueue/v1alpha1/topology_types.go
@@ -120,6 +120,7 @@ type Topology struct {
 	metav1.TypeMeta   `json:",inline"`
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
+	// +kubebuilder:validation:Required
 	Spec TopologySpec `json:"spec,omitempty"`
 }
 
diff --git a/apis/kueue/v1beta1/admissioncheck_types.go b/apis/kueue/v1beta1/admissioncheck_types.go
index 27e438d3e..c481e23ff 100644
--- a/apis/kueue/v1beta1/admissioncheck_types.go
+++ b/apis/kueue/v1beta1/admissioncheck_types.go
@@ -97,15 +97,6 @@ const (
 	// AdmissionCheckActive indicates that the controller of the admission check is
 	// ready to evaluate the checks states
 	AdmissionCheckActive string = "Active"
-
-	// AdmissionChecksSingleInstanceInClusterQueue indicates if the AdmissionCheck should be the only
-	// one managed by the same controller (as determined by the controllerName field) in a ClusterQueue.
-	// Having multiple AdmissionChecks managed by the same controller where at least one has this condition
-	// set to true will cause the ClusterQueue to be marked as Inactive.
-	AdmissionChecksSingleInstanceInClusterQueue string = "SingleInstanceInClusterQueue"
-
-	// FlavorIndependentAdmissionCheck indicates if the AdmissionCheck cannot be applied at ResourceFlavor level.
-	FlavorIndependentAdmissionCheck string = "FlavorIndependent"
 )
 
 // +genclient
diff --git a/apis/kueue/v1beta1/clusterqueue_types.go b/apis/kueue/v1beta1/clusterqueue_types.go
index bbf05c93a..92f735944 100644
--- a/apis/kueue/v1beta1/clusterqueue_types.go
+++ b/apis/kueue/v1beta1/clusterqueue_types.go
@@ -24,19 +24,17 @@ import (
 
 // ClusterQueue Active condition reasons.
 const (
-	ClusterQueueActiveReasonTerminating                                     = "Terminating"
-	ClusterQueueActiveReasonStopped                                         = "Stopped"
-	ClusterQueueActiveReasonFlavorNotFound                                  = "FlavorNotFound"
-	ClusterQueueActiveReasonAdmissionCheckNotFound                          = "AdmissionCheckNotFound"
-	ClusterQueueActiveReasonAdmissionCheckInactive                          = "AdmissionCheckInactive"
-	ClusterQueueActiveReasonMultipleSingleInstanceControllerAdmissionChecks = "MultipleSingleInstanceControllerAdmissionChecks"
-	ClusterQueueActiveReasonFlavorIndependentAdmissionCheckAppliedPerFlavor = "FlavorIndependentAdmissionCheckAppliedPerFlavor"
-	ClusterQueueActiveReasonMultipleMultiKueueAdmissionChecks               = "MultipleMultiKueueAdmissionChecks"
-	ClusterQueueActiveReasonMultiKueueAdmissionCheckAppliedPerFlavor        = "MultiKueueAdmissionCheckAppliedPerFlavor"
-	ClusterQueueActiveReasonNotSupportedWithTopologyAwareScheduling         = "NotSupportedWithTopologyAwareScheduling"
-	ClusterQueueActiveReasonTopologyNotFound                                = "TopologyNotFound"
-	ClusterQueueActiveReasonUnknown                                         = "Unknown"
-	ClusterQueueActiveReasonReady                                           = "Ready"
+	ClusterQueueActiveReasonTerminating                              = "Terminating"
+	ClusterQueueActiveReasonStopped                                  = "Stopped"
+	ClusterQueueActiveReasonFlavorNotFound                           = "FlavorNotFound"
+	ClusterQueueActiveReasonAdmissionCheckNotFound                   = "AdmissionCheckNotFound"
+	ClusterQueueActiveReasonAdmissionCheckInactive                   = "AdmissionCheckInactive"
+	ClusterQueueActiveReasonMultipleMultiKueueAdmissionChecks        = "MultipleMultiKueueAdmissionChecks"
+	ClusterQueueActiveReasonMultiKueueAdmissionCheckAppliedPerFlavor = "MultiKueueAdmissionCheckAppliedPerFlavor"
+	ClusterQueueActiveReasonNotSupportedWithTopologyAwareScheduling  = "NotSupportedWithTopologyAwareScheduling"
+	ClusterQueueActiveReasonTopologyNotFound                         = "TopologyNotFound"
+	ClusterQueueActiveReasonUnknown                                  = "Unknown"
+	ClusterQueueActiveReasonReady                                    = "Ready"
 )
 
 // CohortReference is the name of the Cohort.
@@ -106,7 +104,7 @@ type ClusterQueueSpec struct {
 	// admissionChecks lists the AdmissionChecks required by this ClusterQueue.
 	// Cannot be used along with AdmissionCheckStrategy.
 	// +optional
-	AdmissionChecks []string `json:"admissionChecks,omitempty"`
+	AdmissionChecks []AdmissionCheckReference `json:"admissionChecks,omitempty"`
 
 	// admissionCheckStrategy defines a list of strategies to determine which ResourceFlavors require AdmissionChecks.
 	// This property cannot be used in conjunction with the 'admissionChecks' property.
@@ -143,7 +141,7 @@ type AdmissionChecksStrategy struct {
 // AdmissionCheckStrategyRule defines rules for a single AdmissionCheck
 type AdmissionCheckStrategyRule struct {
 	// name is an AdmissionCheck's name.
-	Name string `json:"name"`
+	Name AdmissionCheckReference `json:"name"`
 
 	// onFlavors is a list of ResourceFlavors' names that this AdmissionCheck should run for.
 	// If empty, the AdmissionCheck will run for all workloads submitted to the ClusterQueue.
diff --git a/apis/kueue/v1beta1/workload_types.go b/apis/kueue/v1beta1/workload_types.go
index 6a717e827..cd65cd80a 100644
--- a/apis/kueue/v1beta1/workload_types.go
+++ b/apis/kueue/v1beta1/workload_types.go
@@ -386,12 +386,15 @@ type RequeueState struct {
 	RequeueAt *metav1.Time `json:"requeueAt,omitempty"`
 }
 
+// AdmissionCheckReference is the name of an AdmissionCheck.
+// +kubebuilder:validation:MaxLength=316
+type AdmissionCheckReference string
+
 type AdmissionCheckState struct {
 	// name identifies the admission check.
 	// +required
 	// +kubebuilder:validation:Required
-	// +kubebuilder:validation:MaxLength=316
-	Name string `json:"name"`
+	Name AdmissionCheckReference `json:"name"`
 	// state of the admissionCheck, one of Pending, Ready, Retry, Rejected
 	// +required
 	// +kubebuilder:validation:Required
@@ -557,13 +560,6 @@ const (
 	// because the LocalQueue is Stopped.
 	WorkloadEvictedByLocalQueueStopped = "LocalQueueStopped"
 
-	// WorkloadEvictedByDeactivation indicates that the workload was evicted
-	// because spec.active is set to false.
-	// Deprecated: The reason is not set any longer, it is only kept temporarily to ensure
-	// pre-existing deactivated workloads remain deactivated after upgrade from version
-	// prior to 0.10. The reason declaration can be removed in 0.11.
-	WorkloadEvictedByDeactivation = "InactiveWorkload"
-
 	// WorkloadDeactivated indicates that the workload was evicted
 	// because spec.active is set to false.
 	WorkloadDeactivated = "Deactivated"
diff --git a/apis/kueue/v1beta1/zz_generated.deepcopy.go b/apis/kueue/v1beta1/zz_generated.deepcopy.go
index abc4a6b4c..ce0789388 100644
--- a/apis/kueue/v1beta1/zz_generated.deepcopy.go
+++ b/apis/kueue/v1beta1/zz_generated.deepcopy.go
@@ -396,7 +396,7 @@ func (in *ClusterQueueSpec) DeepCopyInto(out *ClusterQueueSpec) {
 	}
 	if in.AdmissionChecks != nil {
 		in, out := &in.AdmissionChecks, &out.AdmissionChecks
-		*out = make([]string, len(*in))
+		*out = make([]AdmissionCheckReference, len(*in))
 		copy(*out, *in)
 	}
 	if in.AdmissionChecksStrategy != nil {
diff --git a/charts/kueue/README.md b/charts/kueue/README.md
index 139bbf820..a014a93cb 100644
--- a/charts/kueue/README.md
+++ b/charts/kueue/README.md
@@ -73,7 +73,6 @@ The following table lists the configurable parameters of the kueue chart and the
 | `fullnameOverride`                                     | override the resource name                             | ``                                          |
 | `enablePrometheus`                                     | enable Prometheus                                      | `false`                                     |
 | `enableCertManager`                                    | enable CertManager                                     | `false`                                     |
-| `enableVisibilityAPF`                                  | enable APF for the visibility API                      | `false`                                     |
 | `enableKueueViz`                                       | enable KueueViz dashboard                              | `false`                                     |
 | `KueueViz.backend.image`                               | KueueViz dashboard backend image                       | `us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueueviz-backend:main` |
 | `KueueViz.frontend.image`                              | KueueViz dashboard frontend image                      | `us-central1-docker.pkg.dev/k8s-staging-images/kueue/kueueviz-frontend:main` |
diff --git a/charts/kueue/templates/crd/kueue.x-k8s.io_clusterqueues.yaml b/charts/kueue/templates/crd/kueue.x-k8s.io_clusterqueues.yaml
index 5cb425418..0d696cdd8 100644
--- a/charts/kueue/templates/crd/kueue.x-k8s.io_clusterqueues.yaml
+++ b/charts/kueue/templates/crd/kueue.x-k8s.io_clusterqueues.yaml
@@ -80,6 +80,8 @@ spec:
                   admissionChecks lists the AdmissionChecks required by this ClusterQueue.
                   Cannot be used along with AdmissionCheckStrategy.
                 items:
+                  description: AdmissionCheckReference is the name of an AdmissionCheck.
+                  maxLength: 316
                   type: string
                 type: array
               admissionChecksStrategy:
@@ -95,6 +97,7 @@ spec:
                       properties:
                         name:
                           description: name is an AdmissionCheck's name.
+                          maxLength: 316
                           type: string
                         onFlavors:
                           description: |-
diff --git a/charts/kueue/templates/crd/kueue.x-k8s.io_topologies.yaml b/charts/kueue/templates/crd/kueue.x-k8s.io_topologies.yaml
index 0fb92bf84..edf0519c0 100644
--- a/charts/kueue/templates/crd/kueue.x-k8s.io_topologies.yaml
+++ b/charts/kueue/templates/crd/kueue.x-k8s.io_topologies.yaml
@@ -91,6 +91,8 @@ spec:
             required:
             - levels
             type: object
+        required:
+        - spec
         type: object
     served: true
     storage: true
diff --git a/charts/kueue/templates/visibility-apf/flowschema.yaml b/charts/kueue/templates/visibility/flowschema.yaml
similarity index 93%
rename from charts/kueue/templates/visibility-apf/flowschema.yaml
rename to charts/kueue/templates/visibility/flowschema.yaml
index d43a31a72..18b2e8010 100644
--- a/charts/kueue/templates/visibility-apf/flowschema.yaml
+++ b/charts/kueue/templates/visibility/flowschema.yaml
@@ -1,4 +1,3 @@
-{{- if .Values.enableVisibilityAPF }}
 apiVersion: flowcontrol.apiserver.k8s.io/v1
 kind: FlowSchema
 metadata:
@@ -30,4 +29,3 @@ spec:
         - group:
             name: system:authenticated
           kind: Group
-{{- end }}
diff --git a/charts/kueue/templates/visibility-apf/prioritylevelconfigurations.yaml b/charts/kueue/templates/visibility/prioritylevelconfigurations.yaml
similarity index 90%
rename from charts/kueue/templates/visibility-apf/prioritylevelconfigurations.yaml
rename to charts/kueue/templates/visibility/prioritylevelconfigurations.yaml
index 1175cae2f..970c73dc6 100644
--- a/charts/kueue/templates/visibility-apf/prioritylevelconfigurations.yaml
+++ b/charts/kueue/templates/visibility/prioritylevelconfigurations.yaml
@@ -1,4 +1,3 @@
-{{- if .Values.enableVisibilityAPF }}
 apiVersion: flowcontrol.apiserver.k8s.io/v1
 kind: PriorityLevelConfiguration
 metadata:
@@ -17,4 +16,3 @@ spec:
       type: Queue
     nominalConcurrencyShares: 10
   type: Limited
-{{- end }}
diff --git a/charts/kueue/values.yaml b/charts/kueue/values.yaml
index 1a79a66b7..0ccd09fd8 100644
--- a/charts/kueue/values.yaml
+++ b/charts/kueue/values.yaml
@@ -7,8 +7,6 @@ fullnameOverride: ""
 enablePrometheus: false
 # Enable x509 automated certificate management using cert-manager (cert-manager.io)
 enableCertManager: false
-# Enable API Priority and Fairness configuration for the visibility API
-enableVisibilityAPF: false
 # Customize controllerManager
 controllerManager:
   #featureGates:
diff --git a/client-go/applyconfiguration/kueue/v1beta1/admissioncheckstate.go b/client-go/applyconfiguration/kueue/v1beta1/admissioncheckstate.go
index 64d9a4fb7..7a01f579b 100644
--- a/client-go/applyconfiguration/kueue/v1beta1/admissioncheckstate.go
+++ b/client-go/applyconfiguration/kueue/v1beta1/admissioncheckstate.go
@@ -25,11 +25,11 @@ import (
 // AdmissionCheckStateApplyConfiguration represents a declarative configuration of the AdmissionCheckState type for use
 // with apply.
 type AdmissionCheckStateApplyConfiguration struct {
-	Name               *string                          `json:"name,omitempty"`
-	State              *kueuev1beta1.CheckState         `json:"state,omitempty"`
-	LastTransitionTime *v1.Time                         `json:"lastTransitionTime,omitempty"`
-	Message            *string                          `json:"message,omitempty"`
-	PodSetUpdates      []PodSetUpdateApplyConfiguration `json:"podSetUpdates,omitempty"`
+	Name               *kueuev1beta1.AdmissionCheckReference `json:"name,omitempty"`
+	State              *kueuev1beta1.CheckState              `json:"state,omitempty"`
+	LastTransitionTime *v1.Time                              `json:"lastTransitionTime,omitempty"`
+	Message            *string                               `json:"message,omitempty"`
+	PodSetUpdates      []PodSetUpdateApplyConfiguration      `json:"podSetUpdates,omitempty"`
 }
 
 // AdmissionCheckStateApplyConfiguration constructs a declarative configuration of the AdmissionCheckState type for use with
@@ -41,7 +41,7 @@ func AdmissionCheckState() *AdmissionCheckStateApplyConfiguration {
 // 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 *AdmissionCheckStateApplyConfiguration) WithName(value string) *AdmissionCheckStateApplyConfiguration {
+func (b *AdmissionCheckStateApplyConfiguration) WithName(value kueuev1beta1.AdmissionCheckReference) *AdmissionCheckStateApplyConfiguration {
 	b.Name = &value
 	return b
 }
diff --git a/client-go/applyconfiguration/kueue/v1beta1/admissioncheckstrategyrule.go b/client-go/applyconfiguration/kueue/v1beta1/admissioncheckstrategyrule.go
index a62ad25e2..76f3120ff 100644
--- a/client-go/applyconfiguration/kueue/v1beta1/admissioncheckstrategyrule.go
+++ b/client-go/applyconfiguration/kueue/v1beta1/admissioncheckstrategyrule.go
@@ -24,7 +24,7 @@ import (
 // AdmissionCheckStrategyRuleApplyConfiguration represents a declarative configuration of the AdmissionCheckStrategyRule type for use
 // with apply.
 type AdmissionCheckStrategyRuleApplyConfiguration struct {
-	Name      *string                                `json:"name,omitempty"`
+	Name      *kueuev1beta1.AdmissionCheckReference  `json:"name,omitempty"`
 	OnFlavors []kueuev1beta1.ResourceFlavorReference `json:"onFlavors,omitempty"`
 }
 
@@ -37,7 +37,7 @@ func AdmissionCheckStrategyRule() *AdmissionCheckStrategyRuleApplyConfiguration
 // 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 *AdmissionCheckStrategyRuleApplyConfiguration) WithName(value string) *AdmissionCheckStrategyRuleApplyConfiguration {
+func (b *AdmissionCheckStrategyRuleApplyConfiguration) WithName(value kueuev1beta1.AdmissionCheckReference) *AdmissionCheckStrategyRuleApplyConfiguration {
 	b.Name = &value
 	return b
 }
diff --git a/client-go/applyconfiguration/kueue/v1beta1/clusterqueuespec.go b/client-go/applyconfiguration/kueue/v1beta1/clusterqueuespec.go
index 52564a1f9..41a155d83 100644
--- a/client-go/applyconfiguration/kueue/v1beta1/clusterqueuespec.go
+++ b/client-go/applyconfiguration/kueue/v1beta1/clusterqueuespec.go
@@ -31,7 +31,7 @@ type ClusterQueueSpecApplyConfiguration struct {
 	NamespaceSelector       *v1.LabelSelectorApplyConfiguration        `json:"namespaceSelector,omitempty"`
 	FlavorFungibility       *FlavorFungibilityApplyConfiguration       `json:"flavorFungibility,omitempty"`
 	Preemption              *ClusterQueuePreemptionApplyConfiguration  `json:"preemption,omitempty"`
-	AdmissionChecks         []string                                   `json:"admissionChecks,omitempty"`
+	AdmissionChecks         []kueuev1beta1.AdmissionCheckReference     `json:"admissionChecks,omitempty"`
 	AdmissionChecksStrategy *AdmissionChecksStrategyApplyConfiguration `json:"admissionChecksStrategy,omitempty"`
 	StopPolicy              *kueuev1beta1.StopPolicy                   `json:"stopPolicy,omitempty"`
 	FairSharing             *FairSharingApplyConfiguration             `json:"fairSharing,omitempty"`
@@ -99,7 +99,7 @@ func (b *ClusterQueueSpecApplyConfiguration) WithPreemption(value *ClusterQueueP
 // WithAdmissionChecks adds the given value to the AdmissionChecks field in the declarative configuration
 // and returns the receiver, so that objects can be build by chaining "With" function invocations.
 // If called multiple times, values provided by each call will be appended to the AdmissionChecks field.
-func (b *ClusterQueueSpecApplyConfiguration) WithAdmissionChecks(values ...string) *ClusterQueueSpecApplyConfiguration {
+func (b *ClusterQueueSpecApplyConfiguration) WithAdmissionChecks(values ...kueuev1beta1.AdmissionCheckReference) *ClusterQueueSpecApplyConfiguration {
 	for i := range values {
 		b.AdmissionChecks = append(b.AdmissionChecks, values[i])
 	}
diff --git a/cmd/kueueviz/backend/go.mod b/cmd/kueueviz/backend/go.mod
index b2be70d9c..de44e294e 100644
--- a/cmd/kueueviz/backend/go.mod
+++ b/cmd/kueueviz/backend/go.mod
@@ -1,6 +1,7 @@
 module kueueviz
 
 go 1.24.0
+
 require (
 	github.com/gin-gonic/gin v1.10.0
 	github.com/gorilla/websocket v1.5.3
@@ -62,12 +63,12 @@ require (
 	github.com/ugorji/go/codec v1.2.12 // indirect
 	github.com/x448/float16 v0.8.4 // indirect
 	golang.org/x/arch v0.8.0 // indirect
-	golang.org/x/crypto v0.32.0 // indirect
-	golang.org/x/net v0.33.0 // indirect
+	golang.org/x/crypto v0.36.0 // indirect
+	golang.org/x/net v0.38.0 // indirect
 	golang.org/x/oauth2 v0.25.0 // indirect
-	golang.org/x/sys v0.29.0 // indirect
-	golang.org/x/term v0.28.0 // indirect
-	golang.org/x/text v0.21.0 // indirect
+	golang.org/x/sys v0.31.0 // indirect
+	golang.org/x/term v0.30.0 // indirect
+	golang.org/x/text v0.23.0 // indirect
 	golang.org/x/time v0.8.0 // indirect
 	google.golang.org/protobuf v1.36.1 // indirect
 	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
diff --git a/cmd/kueueviz/backend/go.sum b/cmd/kueueviz/backend/go.sum
index 979569477..292756426 100644
--- a/cmd/kueueviz/backend/go.sum
+++ b/cmd/kueueviz/backend/go.sum
@@ -152,16 +152,16 @@ golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
 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.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
-golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
+golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
+golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
 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/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.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
-golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
+golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
+golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
 golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
 golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -172,14 +172,14 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
-golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
-golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
+golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
 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.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
-golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
 golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg=
 golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
diff --git a/config/components/crd/bases/kueue.x-k8s.io_clusterqueues.yaml b/config/components/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
index 7e6814c71..6d98229ec 100644
--- a/config/components/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
+++ b/config/components/crd/bases/kueue.x-k8s.io_clusterqueues.yaml
@@ -65,6 +65,8 @@ spec:
                   admissionChecks lists the AdmissionChecks required by this ClusterQueue.
                   Cannot be used along with AdmissionCheckStrategy.
                 items:
+                  description: AdmissionCheckReference is the name of an AdmissionCheck.
+                  maxLength: 316
                   type: string
                 type: array
               admissionChecksStrategy:
@@ -80,6 +82,7 @@ spec:
                       properties:
                         name:
                           description: name is an AdmissionCheck's name.
+                          maxLength: 316
                           type: string
                         onFlavors:
                           description: |-
diff --git a/config/components/crd/bases/kueue.x-k8s.io_topologies.yaml b/config/components/crd/bases/kueue.x-k8s.io_topologies.yaml
index a8e6bd866..14b6debc6 100644
--- a/config/components/crd/bases/kueue.x-k8s.io_topologies.yaml
+++ b/config/components/crd/bases/kueue.x-k8s.io_topologies.yaml
@@ -76,6 +76,8 @@ spec:
             required:
             - levels
             type: object
+        required:
+        - spec
         type: object
     served: true
     storage: true
diff --git a/config/components/visibility-apf/kustomization.yaml b/config/components/visibility-apf/kustomization.yaml
deleted file mode 100644
index 40d982fc9..000000000
--- a/config/components/visibility-apf/kustomization.yaml
+++ /dev/null
@@ -1,3 +0,0 @@
-resources:
-- flowschema.yaml
-- prioritylevelconfigurations.yaml
diff --git a/config/components/visibility-apf/flowschema.yaml b/config/components/visibility/flowschema.yaml
similarity index 100%
rename from config/components/visibility-apf/flowschema.yaml
rename to config/components/visibility/flowschema.yaml
diff --git a/config/components/visibility/kustomization.yaml b/config/components/visibility/kustomization.yaml
index cd29a9935..23c787354 100644
--- a/config/components/visibility/kustomization.yaml
+++ b/config/components/visibility/kustomization.yaml
@@ -2,3 +2,5 @@ resources:
 - apiservice_v1beta1.yaml
 - role_binding.yaml
 - service.yaml
+- flowschema.yaml
+- prioritylevelconfigurations.yaml
diff --git a/config/components/visibility-apf/prioritylevelconfigurations.yaml b/config/components/visibility/prioritylevelconfigurations.yaml
similarity index 100%
rename from config/components/visibility-apf/prioritylevelconfigurations.yaml
rename to config/components/visibility/prioritylevelconfigurations.yaml
diff --git a/config/visibility-apf/kustomization.yaml b/config/visibility-apf/kustomization.yaml
deleted file mode 100644
index 847f776a9..000000000
--- a/config/visibility-apf/kustomization.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-# This overlay builds the APF components to be used in combination
-# with other overlays.
-
-namespace: kueue-system
-namePrefix: kueue-
-
-labels:
-  - pairs:
-      app.kubernetes.io/name: kueue
-      app.kubernetes.io/component: controller
-      control-plane: controller-manager
-
-resources:
-  - ../components/visibility-apf/
\ No newline at end of file
diff --git a/go.mod b/go.mod
index c72614c98..9c177b655 100644
--- a/go.mod
+++ b/go.mod
@@ -20,6 +20,7 @@ require (
 	github.com/spf13/cobra v1.9.1
 	github.com/spf13/pflag v1.0.6
 	go.uber.org/zap v1.27.0
+	golang.org/x/sync v0.13.0
 	k8s.io/api v0.32.3
 	k8s.io/apimachinery v0.32.3
 	k8s.io/apiserver v0.32.3
@@ -35,7 +36,7 @@ require (
 	k8s.io/utils v0.0.0-20241210054802-24370beab758
 	sigs.k8s.io/controller-runtime v0.20.4
 	sigs.k8s.io/jobset v0.8.1
-	sigs.k8s.io/lws v0.6.0
+	sigs.k8s.io/lws v0.6.1
 	sigs.k8s.io/structured-merge-diff/v4 v4.7.0
 	sigs.k8s.io/yaml v1.4.0
 )
@@ -123,9 +124,8 @@ require (
 	golang.org/x/crypto v0.36.0 // indirect
 	golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
 	golang.org/x/mod v0.24.0 // indirect
-	golang.org/x/net v0.37.0 // indirect
+	golang.org/x/net v0.38.0 // indirect
 	golang.org/x/oauth2 v0.28.0 // indirect
-	golang.org/x/sync v0.12.0 // indirect
 	golang.org/x/sys v0.32.0 // indirect
 	golang.org/x/term v0.30.0 // indirect
 	golang.org/x/text v0.23.0 // indirect
diff --git a/go.sum b/go.sum
index 340afff0e..2e417ce6c 100644
--- a/go.sum
+++ b/go.sum
@@ -285,15 +285,15 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 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.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
-golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
+golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
 golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
 golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
 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.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
-golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
+golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
 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=
@@ -393,8 +393,8 @@ sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo
 sigs.k8s.io/kustomize/api v0.18.0/go.mod h1:f8isXnX+8b+SGLHQ6yO4JG1rdkZlvhaCf/uZbLVMb0U=
 sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt4E=
 sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo=
-sigs.k8s.io/lws v0.6.0 h1:qHvhm54daBzL1S/+e8bafp7BKRC3jhrqY+EgpDGf41o=
-sigs.k8s.io/lws v0.6.0/go.mod h1:7nbwcpHwdDticuWPTDe6Va5OpjasS0MoVeVD61N5Y0c=
+sigs.k8s.io/lws v0.6.1 h1:cWiRmMSflo8hQPBrmIIZtoaX3XuVkmAgFKkmjxlPULI=
+sigs.k8s.io/lws v0.6.1/go.mod h1:aoT5ROMriBtN/H8JH0POBF6e2uyFCOxKGKtXSA3DVV8=
 sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
 sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
 sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
diff --git a/hack/internal/tools/go.mod b/hack/internal/tools/go.mod
index f1bd4cefc..71dea95bf 100644
--- a/hack/internal/tools/go.mod
+++ b/hack/internal/tools/go.mod
@@ -106,7 +106,7 @@ require (
 	github.com/yuin/gopher-lua v1.1.1 // indirect
 	golang.org/x/crypto v0.36.0 // indirect
 	golang.org/x/mod v0.24.0 // indirect
-	golang.org/x/net v0.37.0 // indirect
+	golang.org/x/net v0.38.0 // indirect
 	golang.org/x/oauth2 v0.26.0 // indirect
 	golang.org/x/sync v0.12.0 // indirect
 	golang.org/x/sys v0.32.0 // indirect
diff --git a/hack/internal/tools/go.sum b/hack/internal/tools/go.sum
index 21874f0b1..46c7a072c 100644
--- a/hack/internal/tools/go.sum
+++ b/hack/internal/tools/go.sum
@@ -267,8 +267,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
 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.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
-golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
+golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
 golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
 golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
diff --git a/hack/update-helm.sh b/hack/update-helm.sh
index ff354d635..95b3cf14e 100755
--- a/hack/update-helm.sh
+++ b/hack/update-helm.sh
@@ -23,14 +23,12 @@ SRC_CRD_DIR=config/components/crd/bases
 SRC_RBAC_DIR=config/components/rbac
 SRC_WEBHOOK_DIR=config/components/webhook
 SRC_VISIBILITY_DIR=config/components/visibility
-SRC_VISIBILITY_APF_DIR=config/components/visibility-apf
 SRC_KUEUEVIZ_DIR=config/components/kueueviz
 
 DEST_CRD_DIR=charts/kueue/templates/crd
 DEST_RBAC_DIR=charts/kueue/templates/rbac
 DEST_WEBHOOK_DIR=charts/kueue/templates/webhook
 DEST_VISIBILITY_DIR=charts/kueue/templates/visibility
-DEST_VISIBILITY_APF_DIR=charts/kueue/templates/visibility-apf
 DEST_KUEUEVIZ_DIR=charts/kueue/templates/kueueviz
 
 YQ=./bin/yq
@@ -53,8 +51,6 @@ find $SRC_WEBHOOK_DIR -name "*.yaml" $EXCLUDE_FILES_ARGS -exec cp "{}" $DEST_WEB
 # shellcheck disable=SC2086
 find $SRC_VISIBILITY_DIR -name "*.yaml" $EXCLUDE_FILES_ARGS -exec cp "{}" $DEST_VISIBILITY_DIR \;
 # shellcheck disable=SC2086
-find $SRC_VISIBILITY_APF_DIR -name "*.yaml" $EXCLUDE_FILES_ARGS -exec cp "{}" $DEST_VISIBILITY_APF_DIR \;
-# shellcheck disable=SC2086
 find $SRC_KUEUEVIZ_DIR -name "*.yaml" $EXCLUDE_FILES_ARGS -exec cp "{}" $DEST_KUEUEVIZ_DIR \;
 $YQ -N -s '.kind' ${DEST_WEBHOOK_DIR}/manifests.yaml
 rm ${DEST_WEBHOOK_DIR}/manifests.yaml
@@ -413,19 +409,6 @@ EOT
   $SED -i '/^metadata:.*/a\  labels:\n  {{- include "kueue.labels" . | nindent 4 }}' "$output_file"
 done
 
-# Replace flowcontrol version on visibility-apf directory
-for output_file in "${DEST_VISIBILITY_APF_DIR}"/*.yaml; do
-  $YQ -N -i '.metadata.name |= "{{ include \"kueue.fullname\" . }}-" + .' "$output_file"
-  $YQ -N -i '.metadata.namespace = "{{ .Release.Namespace }}"' "$output_file"
-  $SED -i '/^metadata:.*/a\  labels:\n  {{- include "kueue.labels" . | nindent 4 }}' "$output_file"
-  {
-    echo '{{- if .Values.enableVisibilityAPF }}'
-    cat "$output_file"
-    echo "{{- end }}"
-  } > "${output_file}.tmp"
-  mv "${output_file}.tmp" "${output_file}"
-done
-
 # Add kueueviz templating on kueueviz directory
 for output_file in "${DEST_KUEUEVIZ_DIR}"/*.yaml; do
   if [ "$(< "$output_file" $YQ '.kind | select(. == "Deployment")')" ]; then
diff --git a/pkg/cache/admissioncheck.go b/pkg/cache/admissioncheck.go
index a6fb50282..e72f743e6 100644
--- a/pkg/cache/admissioncheck.go
+++ b/pkg/cache/admissioncheck.go
@@ -17,8 +17,6 @@ limitations under the License.
 package cache
 
 type AdmissionCheck struct {
-	Active                       bool
-	Controller                   string
-	SingleInstanceInClusterQueue bool
-	FlavorIndependent            bool
+	Active     bool
+	Controller string
 }
diff --git a/pkg/cache/cache.go b/pkg/cache/cache.go
index f19d81b96..0ba5aca82 100644
--- a/pkg/cache/cache.go
+++ b/pkg/cache/cache.go
@@ -107,7 +107,7 @@ type Cache struct {
 	assumedWorkloads    map[string]kueue.ClusterQueueReference
 	resourceFlavors     map[kueue.ResourceFlavorReference]*kueue.ResourceFlavor
 	podsReadyTracking   bool
-	admissionChecks     map[string]AdmissionCheck
+	admissionChecks     map[kueue.AdmissionCheckReference]AdmissionCheck
 	workloadInfoOptions []workload.InfoOption
 	fairSharingEnabled  bool
 
@@ -125,7 +125,7 @@ func New(client client.Client, opts ...Option) *Cache {
 		client:              client,
 		assumedWorkloads:    make(map[string]kueue.ClusterQueueReference),
 		resourceFlavors:     make(map[kueue.ResourceFlavorReference]*kueue.ResourceFlavor),
-		admissionChecks:     make(map[string]AdmissionCheck),
+		admissionChecks:     make(map[kueue.AdmissionCheckReference]AdmissionCheck),
 		podsReadyTracking:   options.podsReadyTracking,
 		workloadInfoOptions: options.workloadInfoOptions,
 		fairSharingEnabled:  options.fairSharingEnabled,
@@ -286,14 +286,7 @@ func (c *Cache) AddOrUpdateAdmissionCheck(ac *kueue.AdmissionCheck) sets.Set[kue
 		Active:     apimeta.IsStatusConditionTrue(ac.Status.Conditions, kueue.AdmissionCheckActive),
 		Controller: ac.Spec.ControllerName,
 	}
-	if features.Enabled(features.AdmissionCheckValidationRules) {
-		newAC.SingleInstanceInClusterQueue = apimeta.IsStatusConditionTrue(ac.Status.Conditions, kueue.AdmissionChecksSingleInstanceInClusterQueue)
-		newAC.FlavorIndependent = apimeta.IsStatusConditionTrue(ac.Status.Conditions, kueue.FlavorIndependentAdmissionCheck)
-	} else if ac.Spec.ControllerName == kueue.MultiKueueControllerName {
-		newAC.SingleInstanceInClusterQueue = true
-		newAC.FlavorIndependent = true
-	}
-	c.admissionChecks[ac.Name] = newAC
+	c.admissionChecks[kueue.AdmissionCheckReference(ac.Name)] = newAC
 
 	return c.updateClusterQueues()
 }
@@ -301,7 +294,7 @@ func (c *Cache) AddOrUpdateAdmissionCheck(ac *kueue.AdmissionCheck) sets.Set[kue
 func (c *Cache) DeleteAdmissionCheck(ac *kueue.AdmissionCheck) sets.Set[kueue.ClusterQueueReference] {
 	c.Lock()
 	defer c.Unlock()
-	delete(c.admissionChecks, ac.Name)
+	delete(c.admissionChecks, kueue.AdmissionCheckReference(ac.Name))
 	return c.updateClusterQueues()
 }
 
@@ -922,7 +915,7 @@ func (c *Cache) ClusterQueuesUsingTopology(tName kueue.TopologyReference) []kueu
 	return cqs
 }
 
-func (c *Cache) ClusterQueuesUsingAdmissionCheck(ac string) []kueue.ClusterQueueReference {
+func (c *Cache) ClusterQueuesUsingAdmissionCheck(ac kueue.AdmissionCheckReference) []kueue.ClusterQueueReference {
 	c.RLock()
 	defer c.RUnlock()
 	var cqs []kueue.ClusterQueueReference
diff --git a/pkg/cache/clusterqueue.go b/pkg/cache/clusterqueue.go
index 8d95df90c..ceafb2d35 100644
--- a/pkg/cache/clusterqueue.go
+++ b/pkg/cache/clusterqueue.go
@@ -36,8 +36,9 @@ import (
 	"sigs.k8s.io/kueue/pkg/hierarchy"
 	"sigs.k8s.io/kueue/pkg/metrics"
 	"sigs.k8s.io/kueue/pkg/resources"
-	utilac "sigs.k8s.io/kueue/pkg/util/admissioncheck"
+	"sigs.k8s.io/kueue/pkg/util/admissioncheck"
 	"sigs.k8s.io/kueue/pkg/util/api"
+	stringsutils "sigs.k8s.io/kueue/pkg/util/strings"
 	"sigs.k8s.io/kueue/pkg/workload"
 )
 
@@ -59,7 +60,7 @@ type clusterQueue struct {
 	// Aggregates AdmissionChecks from both .spec.AdmissionChecks and .spec.AdmissionCheckStrategy
 	// Sets hold ResourceFlavors to which an AdmissionCheck should apply.
 	// In case its empty, it means an AdmissionCheck should apply to all ResourceFlavor
-	AdmissionChecks map[string]sets.Set[kueue.ResourceFlavorReference]
+	AdmissionChecks map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference]
 	Status          metrics.ClusterQueueStatus
 	// AllocatableResourceGeneration will be increased when some admitted workloads are
 	// deleted, or the resource groups are changed.
@@ -67,20 +68,18 @@ type clusterQueue struct {
 
 	AdmittedUsage resources.FlavorResourceQuantities
 	// localQueues by (namespace/name).
-	localQueues                                     map[string]*LocalQueue
-	podsReadyTracking                               bool
-	missingFlavors                                  []kueue.ResourceFlavorReference
-	missingAdmissionChecks                          []string
-	inactiveAdmissionChecks                         []string
-	multipleSingleInstanceControllersChecks         map[string][]string // key = controllerName
-	flavorIndependentAdmissionCheckAppliedPerFlavor []string
-	multiKueueAdmissionChecks                       []string
-	provisioningAdmissionChecks                     []string
-	perFlavorMultiKueueAdmissionChecks              []string
-	tasFlavors                                      map[kueue.ResourceFlavorReference]kueue.TopologyReference
-	admittedWorkloadsCount                          int
-	isStopped                                       bool
-	workloadInfoOptions                             []workload.InfoOption
+	localQueues                        map[string]*LocalQueue
+	podsReadyTracking                  bool
+	missingFlavors                     []kueue.ResourceFlavorReference
+	missingAdmissionChecks             []kueue.AdmissionCheckReference
+	inactiveAdmissionChecks            []kueue.AdmissionCheckReference
+	multiKueueAdmissionChecks          []kueue.AdmissionCheckReference
+	provisioningAdmissionChecks        []kueue.AdmissionCheckReference
+	perFlavorMultiKueueAdmissionChecks []kueue.AdmissionCheckReference
+	tasFlavors                         map[kueue.ResourceFlavorReference]kueue.TopologyReference
+	admittedWorkloadsCount             int
+	isStopped                          bool
+	workloadInfoOptions                []workload.InfoOption
 
 	resourceNode resourceNode
 	hierarchy.ClusterQueue[*cohort]
@@ -113,7 +112,7 @@ var defaultPreemption = kueue.ClusterQueuePreemption{
 
 var defaultFlavorFungibility = kueue.FlavorFungibility{WhenCanBorrow: kueue.Borrow, WhenCanPreempt: kueue.TryNextFlavor}
 
-func (c *clusterQueue) updateClusterQueue(in *kueue.ClusterQueue, resourceFlavors map[kueue.ResourceFlavorReference]*kueue.ResourceFlavor, admissionChecks map[string]AdmissionCheck, oldParent *cohort) error {
+func (c *clusterQueue) updateClusterQueue(in *kueue.ClusterQueue, resourceFlavors map[kueue.ResourceFlavorReference]*kueue.ResourceFlavor, admissionChecks map[kueue.AdmissionCheckReference]AdmissionCheck, oldParent *cohort) error {
 	if c.updateQuotasAndResourceGroups(in.Spec.ResourceGroups) || oldParent != c.Parent() {
 		if oldParent != nil && oldParent != c.Parent() {
 			// ignore error when old Cohort has cycle.
@@ -139,7 +138,7 @@ func (c *clusterQueue) updateClusterQueue(in *kueue.ClusterQueue, resourceFlavor
 
 	c.isStopped = ptr.Deref(in.Spec.StopPolicy, kueue.None) != kueue.None
 
-	c.AdmissionChecks = utilac.NewAdmissionChecks(in)
+	c.AdmissionChecks = admissioncheck.NewAdmissionChecks(in)
 
 	if in.Spec.Preemption != nil {
 		c.Preemption = *in.Spec.Preemption
@@ -201,8 +200,6 @@ func (c *clusterQueue) updateQueueStatus() {
 		len(c.missingFlavors) > 0 ||
 		len(c.missingAdmissionChecks) > 0 ||
 		len(c.inactiveAdmissionChecks) > 0 ||
-		len(c.multipleSingleInstanceControllersChecks) > 0 ||
-		len(c.flavorIndependentAdmissionCheckAppliedPerFlavor) > 0 ||
 		c.isTASViolated() ||
 		// one multikueue admission check is allowed
 		len(c.multiKueueAdmissionChecks) > 1 ||
@@ -244,25 +241,12 @@ func (c *clusterQueue) inactiveReason() (string, string) {
 
 		if len(c.multiKueueAdmissionChecks) > 1 {
 			reasons = append(reasons, kueue.ClusterQueueActiveReasonMultipleMultiKueueAdmissionChecks)
-			messages = append(messages, fmt.Sprintf("Cannot use multiple MultiKueue AdmissionChecks on the same ClusterQueue, found: %v", strings.Join(c.multiKueueAdmissionChecks, ",")))
+			messages = append(messages, fmt.Sprintf("Cannot use multiple MultiKueue AdmissionChecks on the same ClusterQueue, found: %v", stringsutils.Join(c.multiKueueAdmissionChecks, ",")))
 		}
 
 		if len(c.perFlavorMultiKueueAdmissionChecks) > 0 {
 			reasons = append(reasons, kueue.ClusterQueueActiveReasonMultiKueueAdmissionCheckAppliedPerFlavor)
-			messages = append(messages, fmt.Sprintf("Cannot specify MultiKueue AdmissionCheck per flavor, found: %s", strings.Join(c.perFlavorMultiKueueAdmissionChecks, ",")))
-		}
-
-		// This doesn't need to be gated behind, because it is empty when the gate is disabled
-		if len(c.multipleSingleInstanceControllersChecks) > 0 {
-			reasons = append(reasons, kueue.ClusterQueueActiveReasonMultipleSingleInstanceControllerAdmissionChecks)
-			for _, controller := range slices.Sorted(maps.Keys(c.multipleSingleInstanceControllersChecks)) {
-				messages = append(messages, fmt.Sprintf("only one AdmissionCheck of %v can be referenced for controller %q", c.multipleSingleInstanceControllersChecks[controller], controller))
-			}
-		}
-		// This doesn't need to be gated behind, because it is empty when the gate is disabled
-		if len(c.flavorIndependentAdmissionCheckAppliedPerFlavor) > 0 {
-			reasons = append(reasons, kueue.ClusterQueueActiveReasonFlavorIndependentAdmissionCheckAppliedPerFlavor)
-			messages = append(messages, fmt.Sprintf("AdmissionCheck(s): %v cannot be set at flavor level", c.flavorIndependentAdmissionCheckAppliedPerFlavor))
+			messages = append(messages, fmt.Sprintf("Cannot specify MultiKueue AdmissionCheck per flavor, found: %s", stringsutils.Join(c.perFlavorMultiKueueAdmissionChecks, ",")))
 		}
 
 		if features.Enabled(features.TopologyAwareScheduling) && len(c.tasFlavors) > 0 {
@@ -343,15 +327,14 @@ func (c *clusterQueue) updateLabelKeys(flavors map[kueue.ResourceFlavorReference
 }
 
 // updateWithAdmissionChecks updates a ClusterQueue based on the passed AdmissionChecks set.
-func (c *clusterQueue) updateWithAdmissionChecks(checks map[string]AdmissionCheck) {
-	checksPerController := make(map[string][]string, len(c.AdmissionChecks))
+func (c *clusterQueue) updateWithAdmissionChecks(checks map[kueue.AdmissionCheckReference]AdmissionCheck) {
+	checksPerController := make(map[string][]kueue.AdmissionCheckReference, len(c.AdmissionChecks))
 	singleInstanceControllers := sets.New[string]()
-	multiKueueAdmissionChecks := sets.New[string]()
-	provisioningAdmissionChecks := sets.New[string]()
-	var missing []string
-	var inactive []string
-	var flavorIndependentCheckOnFlavors []string
-	var perFlavorMultiKueueChecks []string
+	multiKueueAdmissionChecks := sets.New[kueue.AdmissionCheckReference]()
+	provisioningAdmissionChecks := sets.New[kueue.AdmissionCheckReference]()
+	var missing []kueue.AdmissionCheckReference
+	var inactive []kueue.AdmissionCheckReference
+	var perFlavorMultiKueueChecks []kueue.AdmissionCheckReference
 	for acName, flavors := range c.AdmissionChecks {
 		if ac, found := checks[acName]; !found {
 			missing = append(missing, acName)
@@ -360,13 +343,6 @@ func (c *clusterQueue) updateWithAdmissionChecks(checks map[string]AdmissionChec
 				inactive = append(inactive, acName)
 			}
 			checksPerController[ac.Controller] = append(checksPerController[ac.Controller], acName)
-			if ac.SingleInstanceInClusterQueue {
-				singleInstanceControllers.Insert(ac.Controller)
-			}
-			if ac.FlavorIndependent && flavors.Len() != 0 {
-				flavorIndependentCheckOnFlavors = append(flavorIndependentCheckOnFlavors, acName)
-			}
-
 			if ac.Controller == kueue.ProvisioningRequestControllerName {
 				provisioningAdmissionChecks.Insert(acName)
 			}
@@ -385,7 +361,6 @@ func (c *clusterQueue) updateWithAdmissionChecks(checks map[string]AdmissionChec
 	// sort the lists since c.AdmissionChecks is a map
 	slices.Sort(missing)
 	slices.Sort(inactive)
-	slices.Sort(flavorIndependentCheckOnFlavors)
 	slices.Sort(perFlavorMultiKueueChecks)
 	multiKueueChecks := sets.List(multiKueueAdmissionChecks)
 	provisioningChecks := sets.List(provisioningAdmissionChecks)
@@ -402,7 +377,7 @@ func (c *clusterQueue) updateWithAdmissionChecks(checks map[string]AdmissionChec
 	}
 
 	// remove the controllers which don't have more then one AC or are not single instance.
-	maps.DeleteFunc(checksPerController, func(controller string, acs []string) bool {
+	maps.DeleteFunc(checksPerController, func(controller string, acs []kueue.AdmissionCheckReference) bool {
 		return len(acs) < 2 || !singleInstanceControllers.Has(controller)
 	})
 
@@ -411,18 +386,6 @@ func (c *clusterQueue) updateWithAdmissionChecks(checks map[string]AdmissionChec
 		slices.Sort(checksPerController[c])
 	}
 
-	// Behind the gate due to being triggered when AC is MultiKueue
-	if features.Enabled(features.AdmissionCheckValidationRules) {
-		if !maps.EqualFunc(checksPerController, c.multipleSingleInstanceControllersChecks, slices.Equal) {
-			c.multipleSingleInstanceControllersChecks = checksPerController
-			update = true
-		}
-		if !slices.Equal(c.flavorIndependentAdmissionCheckAppliedPerFlavor, flavorIndependentCheckOnFlavors) {
-			c.flavorIndependentAdmissionCheckAppliedPerFlavor = flavorIndependentCheckOnFlavors
-			update = true
-		}
-	}
-
 	if !slices.Equal(c.multiKueueAdmissionChecks, multiKueueChecks) {
 		c.multiKueueAdmissionChecks = multiKueueChecks
 		update = true
diff --git a/pkg/cache/clusterqueue_snapshot.go b/pkg/cache/clusterqueue_snapshot.go
index 70013cd9c..1e0d514ee 100644
--- a/pkg/cache/clusterqueue_snapshot.go
+++ b/pkg/cache/clusterqueue_snapshot.go
@@ -45,7 +45,7 @@ type ClusterQueueSnapshot struct {
 	// Aggregates AdmissionChecks from both .spec.AdmissionChecks and .spec.AdmissionCheckStrategy
 	// Sets hold ResourceFlavors to which an AdmissionCheck should apply.
 	// In case its empty, it means an AdmissionCheck should apply to all ResourceFlavor
-	AdmissionChecks map[string]sets.Set[kueue.ResourceFlavorReference]
+	AdmissionChecks map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference]
 	Status          metrics.ClusterQueueStatus
 	// AllocatableResourceGeneration will be increased when some admitted workloads are
 	// deleted, or the resource groups are changed.
diff --git a/pkg/cache/cohort_snapshot.go b/pkg/cache/cohort_snapshot.go
index 5dd7c8bf1..bf74056e6 100644
--- a/pkg/cache/cohort_snapshot.go
+++ b/pkg/cache/cohort_snapshot.go
@@ -21,6 +21,7 @@ import (
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/hierarchy"
+	"sigs.k8s.io/kueue/pkg/resources"
 )
 
 type CohortSnapshot struct {
@@ -88,3 +89,7 @@ func (c *CohortSnapshot) parentHRN() hierarchicalResourceNode {
 func (c *CohortSnapshot) fairWeight() *resource.Quantity {
 	return &c.FairWeight
 }
+
+func (c *CohortSnapshot) BorrowingWith(fr resources.FlavorResource, val int64) bool {
+	return c.ResourceNode.Usage[fr]+val > c.ResourceNode.SubtreeQuota[fr]
+}
diff --git a/pkg/cache/resource_node.go b/pkg/cache/resource_node.go
index 650205116..9d4062798 100644
--- a/pkg/cache/resource_node.go
+++ b/pkg/cache/resource_node.go
@@ -19,6 +19,8 @@ package cache
 import (
 	"maps"
 
+	"k8s.io/apimachinery/pkg/util/sets"
+
 	"sigs.k8s.io/kueue/pkg/hierarchy"
 	"sigs.k8s.io/kueue/pkg/resources"
 )
@@ -77,6 +79,13 @@ type hierarchicalResourceNode interface {
 	parentHRN() hierarchicalResourceNode
 }
 
+// LocalAvailable returns, for a given node and resource flavor,
+// how much guaranteed quota in this flavor exceeds usage.
+// This quota is available at this node but is not visible at its parent.
+func LocalAvailable(node hierarchicalResourceNode, fr resources.FlavorResource) int64 {
+	return max(0, node.getResourceNode().guaranteedQuota(fr)-node.getResourceNode().Usage[fr])
+}
+
 // available determines how much capacity remains for the current
 // node, taking into account usage and BorrowingLimits. It finds remaining
 // capacity which is stored locally. If the node has a parent, it
@@ -91,7 +100,6 @@ func available(node hierarchicalResourceNode, fr resources.FlavorResource) int64
 	if !node.HasParent() {
 		return r.SubtreeQuota[fr] - r.Usage[fr]
 	}
-	localAvailable := max(0, r.guaranteedQuota(fr)-r.Usage[fr])
 	parentAvailable := available(node.parentHRN(), fr)
 
 	if borrowingLimit := r.Quotas[fr].BorrowingLimit; borrowingLimit != nil {
@@ -100,7 +108,7 @@ func available(node hierarchicalResourceNode, fr resources.FlavorResource) int64
 		withMaxFromParent := storedInParent - usedInParent + *borrowingLimit
 		parentAvailable = min(withMaxFromParent, parentAvailable)
 	}
-	return localAvailable + parentAvailable
+	return LocalAvailable(node, fr) + parentAvailable
 }
 
 // potentialAvailable returns the maximum capacity available to this node,
@@ -122,7 +130,7 @@ func potentialAvailable(node hierarchicalResourceNode, fr resources.FlavorResour
 // its Cohort when usage exceeds guaranteedQuota.
 func addUsage(node hierarchicalResourceNode, fr resources.FlavorResource, val int64) {
 	r := node.getResourceNode()
-	localAvailable := max(0, r.guaranteedQuota(fr)-r.Usage[fr])
+	localAvailable := LocalAvailable(node, fr)
 	r.Usage[fr] += val
 	if node.HasParent() && val > localAvailable {
 		deltaParentUsage := val - localAvailable
@@ -191,3 +199,30 @@ func accumulateFromChild(parent *cohort, child hierarchicalResourceNode) {
 		parent.resourceNode.Usage[fr] += max(0, childUsage-child.getResourceNode().guaranteedQuota(fr))
 	}
 }
+
+// QuantitiesFitInQuota returns if resource requests fit in quota on this node
+// and the amount of resources that exceed the guaranteed
+// quota on this node. It is assumed that subsequent call
+// to this function will be on nodes parent with remainingRequests
+func QuantitiesFitInQuota(node hierarchicalResourceNode, requests resources.FlavorResourceQuantities) (bool, resources.FlavorResourceQuantities) {
+	fits := true
+	remainingRequests := make(resources.FlavorResourceQuantities, len(requests))
+	for fr, v := range requests {
+		if node.getResourceNode().Usage[fr]+v > node.getResourceNode().SubtreeQuota[fr] {
+			fits = false
+		}
+		remainingRequests[fr] = max(0, v-LocalAvailable(node, fr))
+	}
+	return fits, remainingRequests
+}
+
+// IsWithinNominalInResources returns whether or not, the node quota usage exceeds its
+// nominal quota in any resource flavor out of a set of resource flavours.
+func IsWithinNominalInResources(node hierarchicalResourceNode, frs sets.Set[resources.FlavorResource]) bool {
+	for fr := range frs {
+		if node.getResourceNode().Usage[fr] > node.getResourceNode().SubtreeQuota[fr] {
+			return false
+		}
+	}
+	return true
+}
diff --git a/pkg/cache/snapshot.go b/pkg/cache/snapshot.go
index d8634bb10..42f933acf 100644
--- a/pkg/cache/snapshot.go
+++ b/pkg/cache/snapshot.go
@@ -170,7 +170,7 @@ func snapshotClusterQueue(c *clusterQueue) *ClusterQueueSnapshot {
 		Preemption:                    c.Preemption,
 		NamespaceSelector:             c.NamespaceSelector,
 		Status:                        c.Status,
-		AdmissionChecks:               utilmaps.DeepCopySets[kueue.ResourceFlavorReference](c.AdmissionChecks),
+		AdmissionChecks:               utilmaps.DeepCopySets(c.AdmissionChecks),
 		ResourceNode:                  c.resourceNode.Clone(),
 		TASFlavors:                    make(map[kueue.ResourceFlavorReference]*TASFlavorSnapshot),
 		tasOnly:                       c.isTASOnly(),
diff --git a/pkg/cache/tas_flavor_snapshot.go b/pkg/cache/tas_flavor_snapshot.go
index f525bb33b..4fbde49c7 100644
--- a/pkg/cache/tas_flavor_snapshot.go
+++ b/pkg/cache/tas_flavor_snapshot.go
@@ -26,6 +26,7 @@ import (
 
 	"github.com/go-logr/logr"
 	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/labels"
 	corev1helpers "k8s.io/component-helpers/scheduling/corev1"
 	"k8s.io/utils/ptr"
 
@@ -83,6 +84,10 @@ type leafDomain struct {
 	// nodeTaints contains the list of taints for the node, only applies for
 	// lowest level of topology, if the lowest level is node
 	nodeTaints []corev1.Taint
+
+	// nodeLabels contains the list of labels on the node, only applies for
+	// lowest level of topology, if the lowest level is node
+	nodeLabels map[string]string
 }
 
 type domainByID map[utiltas.TopologyDomainID]*domain
@@ -150,6 +155,7 @@ func (s *TASFlavorSnapshot) addNode(node corev1.Node) utiltas.TopologyDomainID {
 		}
 		if s.isLowestLevelNode() {
 			leafDomain.nodeTaints = slices.Clone(node.Spec.Taints)
+			leafDomain.nodeLabels = node.GetLabels()
 		}
 		s.leaves[domainID] = &leafDomain
 	}
@@ -410,6 +416,7 @@ func (s *TASFlavorSnapshot) findTopologyAssignment(
 	requests := tasPodSetRequests.SinglePodRequests.Clone()
 	requests.Add(resources.Requests{corev1.ResourcePods: 1})
 	podSetTolerations := tasPodSetRequests.PodSet.Template.Spec.Tolerations
+	podSetNodeSelectors := tasPodSetRequests.PodSet.Template.Spec.NodeSelector
 	count := tasPodSetRequests.Count
 	required := isRequired(tasPodSetRequests.PodSet.TopologyRequest)
 	key := s.levelKeyWithImpliedFallback(&tasPodSetRequests)
@@ -421,8 +428,24 @@ func (s *TASFlavorSnapshot) findTopologyAssignment(
 	if !found {
 		return nil, fmt.Sprintf("no requested topology level: %s", *key)
 	}
+	var selector labels.Selector
+	if s.isLowestLevelNode() {
+		sel, err := labels.ValidatedSelectorFromSet(podSetNodeSelectors)
+		if err != nil {
+			return nil, fmt.Sprintf("invalid node selectors: %s, reason: %s", podSetNodeSelectors, err)
+		}
+		selector = sel
+	} else {
+		selector = labels.Everything()
+	}
 	// phase 1 - determine the number of pods which can fit in each topology domain
-	s.fillInCounts(requests, assumedUsage, simulateEmpty, append(podSetTolerations, s.tolerations...))
+	s.fillInCounts(
+		requests,
+		assumedUsage,
+		simulateEmpty,
+		append(podSetTolerations, s.tolerations...),
+		selector,
+	)
 
 	// phase 2a: determine the level at which the assignment is done along with
 	// the domains which can accommodate all pods
@@ -647,13 +670,15 @@ func (s *TASFlavorSnapshot) sortedDomains(domains []*domain, unconstrained bool)
 func (s *TASFlavorSnapshot) fillInCounts(requests resources.Requests,
 	assumedUsage map[utiltas.TopologyDomainID]resources.Requests,
 	simulateEmpty bool,
-	tolerations []corev1.Toleration) {
+	tolerations []corev1.Toleration,
+	selector labels.Selector) {
 	for _, domain := range s.domains {
 		// cleanup the state in case some remaining values are present from computing
 		// assignments for previous PodSets.
 		domain.state = 0
 	}
 	for _, leaf := range s.leaves {
+		// 1. Check Tolerations against Node Taints
 		taint, untolerated := corev1helpers.FindMatchingUntoleratedTaint(leaf.nodeTaints, tolerations, func(t *corev1.Taint) bool {
 			return t.Effect == corev1.TaintEffectNoSchedule || t.Effect == corev1.TaintEffectNoExecute
 		})
@@ -661,6 +686,17 @@ func (s *TASFlavorSnapshot) fillInCounts(requests resources.Requests,
 			s.log.V(2).Info("excluding node with untolerated taint", "domainID", leaf.id, "taint", taint)
 			continue
 		}
+		// 2. Check Node Labels against Compiled Selector
+		var nodeLabelSet labels.Set
+		if leaf.nodeLabels != nil {
+			nodeLabelSet = leaf.nodeLabels
+		}
+		// isLowestLevelNode() is necessary because we gather node level information only when
+		// node is the lowest level of the topology
+		if s.isLowestLevelNode() && !selector.Matches(nodeLabelSet) {
+			s.log.V(2).Info("excluding node that doesn't match nodeSelectors", "domainID", leaf.id, "nodeLabels", nodeLabelSet)
+			continue
+		}
 		remainingCapacity := leaf.freeCapacity.Clone()
 		if !simulateEmpty {
 			remainingCapacity.Sub(leaf.tasUsage)
diff --git a/pkg/controller/admissionchecks/multikueue/admissioncheck.go b/pkg/controller/admissionchecks/multikueue/admissioncheck.go
index 5ef7a0956..20416f528 100644
--- a/pkg/controller/admissionchecks/multikueue/admissioncheck.go
+++ b/pkg/controller/admissionchecks/multikueue/admissioncheck.go
@@ -34,17 +34,9 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
-	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/util/admissioncheck"
 )
 
-const (
-	SingleInstanceReason          = "MultiKueue"
-	SingleInstanceMessage         = "only one multikueue managed admission check can be used in one ClusterQueue"
-	FlavorIndependentCheckReason  = "MultiKueue"
-	FlavorIndependentCheckMessage = "admission check cannot be applied at ResourceFlavor level"
-)
-
 type multiKueueStoreHelper = admissioncheck.ConfigHelper[*kueue.MultiKueueConfig, kueue.MultiKueueConfig]
 
 func newMultiKueueStoreHelper(c client.Client) (*multiKueueStoreHelper, error) {
@@ -128,29 +120,6 @@ func (a *ACReconciler) Reconcile(ctx context.Context, req reconcile.Request) (re
 		needsUpdate = true
 	}
 
-	if features.Enabled(features.AdmissionCheckValidationRules) {
-		if !apimeta.IsStatusConditionTrue(ac.Status.Conditions, kueue.AdmissionChecksSingleInstanceInClusterQueue) {
-			apimeta.SetStatusCondition(&ac.Status.Conditions, metav1.Condition{
-				Type:               kueue.AdmissionChecksSingleInstanceInClusterQueue,
-				Status:             metav1.ConditionTrue,
-				Reason:             SingleInstanceReason,
-				Message:            SingleInstanceMessage,
-				ObservedGeneration: ac.Generation,
-			})
-			needsUpdate = true
-		}
-
-		if !apimeta.IsStatusConditionTrue(ac.Status.Conditions, kueue.FlavorIndependentAdmissionCheck) {
-			apimeta.SetStatusCondition(&ac.Status.Conditions, metav1.Condition{
-				Type:               kueue.FlavorIndependentAdmissionCheck,
-				Status:             metav1.ConditionTrue,
-				Reason:             FlavorIndependentCheckReason,
-				Message:            FlavorIndependentCheckMessage,
-				ObservedGeneration: ac.Generation,
-			})
-			needsUpdate = true
-		}
-	}
 	if needsUpdate {
 		err := a.client.Status().Update(ctx, ac)
 		if err != nil {
diff --git a/pkg/controller/admissionchecks/multikueue/workload.go b/pkg/controller/admissionchecks/multikueue/workload.go
index a16816d7f..0f8065c34 100644
--- a/pkg/controller/admissionchecks/multikueue/workload.go
+++ b/pkg/controller/admissionchecks/multikueue/workload.go
@@ -72,7 +72,7 @@ type wlGroup struct {
 	local         *kueue.Workload
 	remotes       map[string]*kueue.Workload
 	remoteClients map[string]*remoteClient
-	acName        string
+	acName        kueue.AdmissionCheckReference
 	jobAdapter    jobframework.MultiKueueAdapter
 	controllerKey types.NamespacedName
 }
@@ -250,7 +250,7 @@ func (w *wlReconciler) updateACS(ctx context.Context, wl *kueue.Workload, acs *k
 	return w.client.Status().Patch(ctx, wlPatch, client.Apply, client.FieldOwner(kueue.MultiKueueControllerName), client.ForceOwnership)
 }
 
-func (w *wlReconciler) remoteClientsForAC(ctx context.Context, acName string) (map[string]*remoteClient, error) {
+func (w *wlReconciler) remoteClientsForAC(ctx context.Context, acName kueue.AdmissionCheckReference) (map[string]*remoteClient, error) {
 	cfg, err := w.helper.ConfigForAdmissionCheck(ctx, acName)
 	if err != nil {
 		return nil, err
@@ -295,7 +295,7 @@ func (w *wlReconciler) adapter(local *kueue.Workload) (jobframework.MultiKueueAd
 	return nil, nil
 }
 
-func (w *wlReconciler) readGroup(ctx context.Context, local *kueue.Workload, acName string, adapter jobframework.MultiKueueAdapter, controllerName string) (*wlGroup, error) {
+func (w *wlReconciler) readGroup(ctx context.Context, local *kueue.Workload, acName kueue.AdmissionCheckReference, adapter jobframework.MultiKueueAdapter, controllerName string) (*wlGroup, error) {
 	rClients, err := w.remoteClientsForAC(ctx, acName)
 	if err != nil {
 		return nil, fmt.Errorf("admission check %q: %w", acName, err)
diff --git a/pkg/controller/admissionchecks/provisioning/controller.go b/pkg/controller/admissionchecks/provisioning/controller.go
index 9996feeb1..e6d2811d6 100644
--- a/pkg/controller/admissionchecks/provisioning/controller.go
+++ b/pkg/controller/admissionchecks/provisioning/controller.go
@@ -23,7 +23,6 @@ import (
 	"errors"
 	"fmt"
 	"maps"
-	"time"
 
 	corev1 "k8s.io/api/core/v1"
 	apimeta "k8s.io/apimachinery/pkg/api/meta"
@@ -45,7 +44,6 @@ import (
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/constants"
-	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/podset"
 	"sigs.k8s.io/kueue/pkg/util/admissioncheck"
 	"sigs.k8s.io/kueue/pkg/util/api"
@@ -139,7 +137,7 @@ func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (reco
 		return reconcile.Result{}, err
 	}
 
-	checkConfig := make(map[string]*kueue.ProvisioningRequestConfig, len(relevantChecks))
+	checkConfig := make(map[kueue.AdmissionCheckReference]*kueue.ProvisioningRequestConfig, len(relevantChecks))
 	for _, checkName := range relevantChecks {
 		prc, err := c.helper.ConfigForAdmissionCheck(ctx, checkName)
 		if client.IgnoreNotFound(err) != nil {
@@ -164,26 +162,23 @@ func (c *Controller) Reconcile(ctx context.Context, req reconcile.Request) (reco
 		return reconcile.Result{}, err
 	}
 
-	requeueAfter, err := c.syncOwnedProvisionRequest(ctx, wl, &wlInfo, checkConfig, activeOrLastPRForChecks)
+	err = c.syncOwnedProvisionRequest(ctx, wl, &wlInfo, checkConfig, activeOrLastPRForChecks)
 	if err != nil {
 		// this can also delete unneeded checks
 		log.V(2).Error(err, "syncOwnedProvisionRequest failed")
 		return reconcile.Result{}, err
 	}
 
-	if requeueAfter != nil {
-		return reconcile.Result{RequeueAfter: *requeueAfter}, nil
-	}
 	return reconcile.Result{}, nil
 }
 
 func (c *Controller) activeOrLastPRForChecks(
 	ctx context.Context,
 	wl *kueue.Workload,
-	checkConfig map[string]*kueue.ProvisioningRequestConfig,
+	checkConfig map[kueue.AdmissionCheckReference]*kueue.ProvisioningRequestConfig,
 	ownedPRs []autoscaling.ProvisioningRequest,
-) map[string]*autoscaling.ProvisioningRequest {
-	activeOrLastPRForChecks := make(map[string]*autoscaling.ProvisioningRequest)
+) map[kueue.AdmissionCheckReference]*autoscaling.ProvisioningRequest {
+	activeOrLastPRForChecks := make(map[kueue.AdmissionCheckReference]*autoscaling.ProvisioningRequest)
 	log := ctrl.LoggerFrom(ctx)
 	for checkName, prc := range checkConfig {
 		if prc == nil {
@@ -205,7 +200,7 @@ func (c *Controller) activeOrLastPRForChecks(
 	return activeOrLastPRForChecks
 }
 
-func (c *Controller) deleteUnusedProvisioningRequests(ctx context.Context, ownedPRs []autoscaling.ProvisioningRequest, activeOrLastPRForChecks map[string]*autoscaling.ProvisioningRequest) error {
+func (c *Controller) deleteUnusedProvisioningRequests(ctx context.Context, ownedPRs []autoscaling.ProvisioningRequest, activeOrLastPRForChecks map[kueue.AdmissionCheckReference]*autoscaling.ProvisioningRequest) error {
 	log := ctrl.LoggerFrom(ctx)
 	prNames := sets.New[string]()
 	for _, pr := range activeOrLastPRForChecks {
@@ -227,11 +222,10 @@ func (c *Controller) syncOwnedProvisionRequest(
 	ctx context.Context,
 	wl *kueue.Workload,
 	wlInfo *workloadInfo,
-	checkConfig map[string]*kueue.ProvisioningRequestConfig,
-	activeOrLastPRForChecks map[string]*autoscaling.ProvisioningRequest,
-) (*time.Duration, error) {
+	checkConfig map[kueue.AdmissionCheckReference]*kueue.ProvisioningRequestConfig,
+	activeOrLastPRForChecks map[kueue.AdmissionCheckReference]*autoscaling.ProvisioningRequest,
+) error {
 	log := ctrl.LoggerFrom(ctx)
-	var requeAfter *time.Duration
 	for checkName, prc := range checkConfig {
 		if prc == nil {
 			// the check is not active
@@ -255,18 +249,8 @@ func (c *Controller) syncOwnedProvisionRequest(
 				ac != nil && ac.State == kueue.CheckStatePending {
 				// if the workload is in Retry/Rejected state we don't create another ProvReq
 				attempt = getAttempt(log, req, wl.Name, checkName)
-				if features.Enabled(features.KeepQuotaForProvReqRetry) {
-					remainingTime := c.remainingTimeToRetry(req, attempt, prc)
-					if remainingTime <= 0 {
-						shouldCreatePr = true
-						attempt++
-					} else if requeAfter == nil || remainingTime < *requeAfter {
-						requeAfter = &remainingTime
-					}
-				} else {
-					shouldCreatePr = true
-					attempt++
-				}
+				shouldCreatePr = true
+				attempt++
 			}
 		} else {
 			shouldCreatePr = true
@@ -296,7 +280,7 @@ func (c *Controller) syncOwnedProvisionRequest(
 				ps, psFound := podSetMap[psName]
 				psa, psaFound := psaMap[psName]
 				if !psFound || !psaFound {
-					return nil, errInconsistentPodSetAssignments
+					return errInconsistentPodSetAssignments
 				}
 
 				ptName := getProvisioningRequestPodTemplateName(requestName, psName)
@@ -304,14 +288,14 @@ func (c *Controller) syncOwnedProvisionRequest(
 				pt := &corev1.PodTemplate{}
 				err := c.client.Get(ctx, types.NamespacedName{Namespace: wl.Namespace, Name: ptName}, pt)
 				if client.IgnoreNotFound(err) != nil {
-					return nil, err
+					return err
 				}
 				if err != nil {
 					// it's a not found, so create it
 					_, err := c.createPodTemplate(ctx, wl, ptName, ps, psa)
 					if err != nil {
 						msg := fmt.Sprintf("Error creating PodTemplate %q: %v", ptName, err)
-						return nil, c.handleError(ctx, wl, ac, msg, err)
+						return c.handleError(ctx, wl, ac, msg, err)
 					}
 				}
 
@@ -324,41 +308,21 @@ func (c *Controller) syncOwnedProvisionRequest(
 			}
 
 			if err := ctrl.SetControllerReference(wl, req, c.client.Scheme()); err != nil {
-				return nil, err
+				return err
 			}
 
 			if err := c.client.Create(ctx, req); err != nil {
 				msg := fmt.Sprintf("Error creating ProvisioningRequest %q: %v", requestName, err)
-				return nil, c.handleError(ctx, wl, ac, msg, err)
+				return c.handleError(ctx, wl, ac, msg, err)
 			}
 			c.record.Eventf(wl, corev1.EventTypeNormal, "ProvisioningRequestCreated", "Created ProvisioningRequest: %q", req.Name)
 			activeOrLastPRForChecks[checkName] = req
 		}
 		if err := c.syncProvisionRequestsPodTemplates(ctx, wl, req); err != nil {
-			return nil, err
-		}
-	}
-	return requeAfter, nil
-}
-
-func (c *Controller) remainingTimeToRetry(pr *autoscaling.ProvisioningRequest, failuresCount int32, prc *kueue.ProvisioningRequestConfig) time.Duration {
-	backoffDuration := time.Duration(*prc.Spec.RetryStrategy.BackoffBaseSeconds) * time.Second
-	maxBackoffDuration := time.Duration(*prc.Spec.RetryStrategy.BackoffMaxSeconds) * time.Second
-	var cond *metav1.Condition
-	if isFailed(pr) {
-		cond = apimeta.FindStatusCondition(pr.Status.Conditions, autoscaling.Failed)
-	} else {
-		cond = apimeta.FindStatusCondition(pr.Status.Conditions, autoscaling.BookingExpired)
-	}
-	for i := 1; i < int(failuresCount); i++ {
-		backoffDuration *= 2
-		if backoffDuration >= maxBackoffDuration {
-			backoffDuration = maxBackoffDuration
-			break
+			return err
 		}
 	}
-	timeElapsedSinceLastFailure := time.Since(cond.LastTransitionTime.Time)
-	return backoffDuration - timeElapsedSinceLastFailure
+	return nil
 }
 
 func (c *Controller) handleError(ctx context.Context, wl *kueue.Workload, ac *kueue.AdmissionCheckState, msg string, err error) error {
@@ -530,12 +494,12 @@ func (wlInfo *workloadInfo) update(wl *kueue.Workload, c clock.Clock) {
 func (c *Controller) syncCheckStates(
 	ctx context.Context, wl *kueue.Workload,
 	wlInfo *workloadInfo,
-	checkConfig map[string]*kueue.ProvisioningRequestConfig,
-	activeOrLastPRForChecks map[string]*autoscaling.ProvisioningRequest,
+	checkConfig map[kueue.AdmissionCheckReference]*kueue.ProvisioningRequestConfig,
+	activeOrLastPRForChecks map[kueue.AdmissionCheckReference]*autoscaling.ProvisioningRequest,
 ) error {
 	log := ctrl.LoggerFrom(ctx)
 	wlInfo.update(wl, c.clock)
-	checksMap := slices.ToRefMap(wl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return c.Name })
+	checksMap := slices.ToRefMap(wl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) kueue.AdmissionCheckReference { return c.Name })
 	wlPatch := workload.BaseSSAWorkload(wl)
 	recorderMessages := make([]string, 0, len(checkConfig))
 	updated := false
@@ -574,9 +538,7 @@ func (c *Controller) syncCheckStates(
 					// it is going to be retried
 					message := fmt.Sprintf("Retrying after failure: %s", apimeta.FindStatusCondition(pr.Status.Conditions, autoscaling.Failed).Message)
 					updated = updateCheckMessage(&checkState, message) || updated
-					if features.Enabled(features.KeepQuotaForProvReqRetry) {
-						updated = updateCheckState(&checkState, kueue.CheckStatePending) || updated
-					} else if wl.Status.RequeueState == nil || getAttempt(log, pr, wl.Name, check) > ptr.Deref(wl.Status.RequeueState.Count, 0) {
+					if wl.Status.RequeueState == nil || getAttempt(log, pr, wl.Name, check) > ptr.Deref(wl.Status.RequeueState.Count, 0) {
 						// We don't want to Retry on old ProvisioningRequests
 						updated = true
 						updateCheckState(&checkState, kueue.CheckStateRetry)
@@ -601,9 +563,7 @@ func (c *Controller) syncCheckStates(
 						// it is going to be retried
 						message := fmt.Sprintf("Retrying after booking expired: %s", apimeta.FindStatusCondition(pr.Status.Conditions, autoscaling.BookingExpired).Message)
 						updated = updateCheckMessage(&checkState, message) || updated
-						if features.Enabled(features.KeepQuotaForProvReqRetry) {
-							updated = updateCheckState(&checkState, kueue.CheckStatePending) || updated
-						} else if wl.Status.RequeueState == nil || getAttempt(log, pr, wl.Name, check) > ptr.Deref(wl.Status.RequeueState.Count, 0) {
+						if wl.Status.RequeueState == nil || getAttempt(log, pr, wl.Name, check) > ptr.Deref(wl.Status.RequeueState.Count, 0) {
 							updated = true
 							updateCheckState(&checkState, kueue.CheckStateRetry)
 							workload.UpdateRequeueState(wlPatch, backoffBaseSeconds, backoffMaxSeconds, c.clock)
diff --git a/pkg/controller/admissionchecks/provisioning/indexer.go b/pkg/controller/admissionchecks/provisioning/indexer.go
index 12252cc59..80150c682 100644
--- a/pkg/controller/admissionchecks/provisioning/indexer.go
+++ b/pkg/controller/admissionchecks/provisioning/indexer.go
@@ -54,7 +54,7 @@ func indexWorkloadsChecks(obj client.Object) []string {
 	if !isWl || len(wl.Status.AdmissionChecks) == 0 {
 		return nil
 	}
-	return slices.Map(wl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return c.Name })
+	return slices.Map(wl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return string(c.Name) })
 }
 
 func SetupIndexer(ctx context.Context, indexer client.FieldIndexer) error {
diff --git a/pkg/controller/admissionchecks/provisioning/provisioning.go b/pkg/controller/admissionchecks/provisioning/provisioning.go
index 0f5476b48..341864a8e 100644
--- a/pkg/controller/admissionchecks/provisioning/provisioning.go
+++ b/pkg/controller/admissionchecks/provisioning/provisioning.go
@@ -52,12 +52,12 @@ func isCapacityRevoked(pr *autoscaling.ProvisioningRequest) bool {
 	return apimeta.IsStatusConditionTrue(pr.Status.Conditions, autoscaling.CapacityRevoked)
 }
 
-func ProvisioningRequestName(workloadName, checkName string, attempt int32) string {
+func ProvisioningRequestName(workloadName string, checkName kueue.AdmissionCheckReference, attempt int32) string {
 	fullName := fmt.Sprintf("%s-%s-%d", workloadName, checkName, int(attempt))
 	return limitObjectName(fullName)
 }
 
-func getProvisioningRequestNamePrefix(workloadName, checkName string) string {
+func getProvisioningRequestNamePrefix(workloadName string, checkName kueue.AdmissionCheckReference) string {
 	fullName := fmt.Sprintf("%s-%s-", workloadName, checkName)
 	return limitObjectName(fullName)
 }
@@ -67,13 +67,13 @@ func getProvisioningRequestPodTemplateName(prName string, podsetName kueue.PodSe
 	return limitObjectName(fullName)
 }
 
-func matchesWorkloadAndCheck(pr *autoscaling.ProvisioningRequest, workloadName, checkName string) bool {
+func matchesWorkloadAndCheck(pr *autoscaling.ProvisioningRequest, workloadName string, checkName kueue.AdmissionCheckReference) bool {
 	attemptRegex := getAttemptRegex(workloadName, checkName)
 	matches := attemptRegex.FindStringSubmatch(pr.Name)
 	return len(matches) > 0
 }
 
-func getAttempt(log logr.Logger, pr *autoscaling.ProvisioningRequest, workloadName, checkName string) int32 {
+func getAttempt(log logr.Logger, pr *autoscaling.ProvisioningRequest, workloadName string, checkName kueue.AdmissionCheckReference) int32 {
 	attemptRegex := getAttemptRegex(workloadName, checkName)
 	matches := attemptRegex.FindStringSubmatch(pr.Name)
 	if len(matches) > 0 {
@@ -88,7 +88,7 @@ func getAttempt(log logr.Logger, pr *autoscaling.ProvisioningRequest, workloadNa
 	return 1
 }
 
-func getAttemptRegex(workloadName, checkName string) *regexp.Regexp {
+func getAttemptRegex(workloadName string, checkName kueue.AdmissionCheckReference) *regexp.Regexp {
 	prefix := getProvisioningRequestNamePrefix(workloadName, checkName)
 	escapedPrefix := regexp.QuoteMeta(prefix)
 	return regexp.MustCompile("^" + escapedPrefix + "([0-9]+)$")
diff --git a/pkg/controller/core/admissioncheck_controller.go b/pkg/controller/core/admissioncheck_controller.go
index e79cddfd3..cfb374127 100644
--- a/pkg/controller/core/admissioncheck_controller.go
+++ b/pkg/controller/core/admissioncheck_controller.go
@@ -99,7 +99,7 @@ func (r *AdmissionCheckReconciler) Reconcile(ctx context.Context, req ctrl.Reque
 		}
 	} else {
 		if controllerutil.ContainsFinalizer(ac, kueue.ResourceInUseFinalizerName) {
-			if cqs := r.cache.ClusterQueuesUsingAdmissionCheck(ac.Name); len(cqs) != 0 {
+			if cqs := r.cache.ClusterQueuesUsingAdmissionCheck(kueue.AdmissionCheckReference(ac.Name)); len(cqs) != 0 {
 				log.V(3).Info("admissionCheck is still in use", "ClusterQueues", cqs)
 				// We avoid to return error here to prevent backoff requeue, which is passive and wasteful.
 				// Instead, we drive the removal of finalizer by ClusterQueue Update/Delete events
@@ -200,7 +200,7 @@ func (h *acCqHandler) Generic(ctx context.Context, e event.GenericEvent, q workq
 		if cqs := h.cache.ClusterQueuesUsingAdmissionCheck(ac); len(cqs) == 0 {
 			req := reconcile.Request{
 				NamespacedName: types.NamespacedName{
-					Name: ac,
+					Name: string(ac),
 				},
 			}
 			q.Add(req)
diff --git a/pkg/controller/core/clusterqueue_controller.go b/pkg/controller/core/clusterqueue_controller.go
index 596dde967..e49f96650 100644
--- a/pkg/controller/core/clusterqueue_controller.go
+++ b/pkg/controller/core/clusterqueue_controller.go
@@ -297,14 +297,14 @@ func (r *ClusterQueueReconciler) NotifyResourceFlavorUpdate(oldRF, newRF *kueue.
 }
 
 func (r *ClusterQueueReconciler) NotifyAdmissionCheckUpdate(oldAc, newAc *kueue.AdmissionCheck) {
-	var acName string
+	var acName kueue.AdmissionCheckReference
 	switch {
 	case oldAc != nil:
 		// Delete or Update Event.
-		acName = oldAc.Name
+		acName = kueue.AdmissionCheckReference(oldAc.Name)
 	case newAc != nil:
 		// Create Event.
-		acName = newAc.Name
+		acName = kueue.AdmissionCheckReference(newAc.Name)
 	default:
 		return
 	}
diff --git a/pkg/controller/core/workload_controller.go b/pkg/controller/core/workload_controller.go
index 6619edafa..b7f59f9d5 100644
--- a/pkg/controller/core/workload_controller.go
+++ b/pkg/controller/core/workload_controller.go
@@ -54,7 +54,7 @@ import (
 	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/metrics"
 	"sigs.k8s.io/kueue/pkg/queue"
-	utilac "sigs.k8s.io/kueue/pkg/util/admissioncheck"
+	"sigs.k8s.io/kueue/pkg/util/admissioncheck"
 	utilslices "sigs.k8s.io/kueue/pkg/util/slices"
 	"sigs.k8s.io/kueue/pkg/workload"
 )
@@ -168,7 +168,7 @@ func (r *WorkloadReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
 		var updated bool
 		if cond := apimeta.FindStatusCondition(wl.Status.Conditions, kueue.WorkloadRequeued); cond != nil && cond.Status == metav1.ConditionFalse {
 			switch cond.Reason {
-			case kueue.WorkloadDeactivated, kueue.WorkloadEvictedByDeactivation:
+			case kueue.WorkloadDeactivated:
 				workload.SetRequeuedCondition(&wl, kueue.WorkloadReactivated, "The workload was reactivated", true)
 				updated = true
 			case kueue.WorkloadEvictedByPodsReadyTimeout, kueue.WorkloadEvictedByAdmissionCheck:
@@ -381,7 +381,7 @@ func (r *WorkloadReconciler) reconcileCheckBasedEviction(ctx context.Context, wl
 	log := ctrl.LoggerFrom(ctx)
 	log.V(3).Info("Workload is evicted due to admission checks")
 	if workload.HasRejectedChecks(wl) {
-		var rejectedCheckNames []string
+		var rejectedCheckNames []kueue.AdmissionCheckReference
 		for _, check := range workload.RejectedChecks(wl) {
 			rejectedCheckNames = append(rejectedCheckNames, check.Name)
 		}
@@ -408,7 +408,7 @@ func (r *WorkloadReconciler) reconcileCheckBasedEviction(ctx context.Context, wl
 
 func (r *WorkloadReconciler) reconcileSyncAdmissionChecks(ctx context.Context, wl *kueue.Workload, cq *kueue.ClusterQueue) (bool, error) {
 	log := ctrl.LoggerFrom(ctx)
-	admissionChecks := workload.AdmissionChecksForWorkload(log, wl, utilac.NewAdmissionChecks(cq))
+	admissionChecks := workload.AdmissionChecksForWorkload(log, wl, admissioncheck.NewAdmissionChecks(cq))
 	newChecks, shouldUpdate := syncAdmissionCheckConditions(wl.Status.AdmissionChecks, admissionChecks, r.clock)
 	if shouldUpdate {
 		log.V(3).Info("The workload needs admission checks updates", "clusterQueue", klog.KRef("", cq.Name), "admissionChecks", admissionChecks)
@@ -508,13 +508,13 @@ func (r *WorkloadReconciler) reconcileOnClusterQueueActiveState(ctx context.Cont
 	return false, nil
 }
 
-func syncAdmissionCheckConditions(conds []kueue.AdmissionCheckState, admissionChecks sets.Set[string], c clock.Clock) ([]kueue.AdmissionCheckState, bool) {
+func syncAdmissionCheckConditions(conds []kueue.AdmissionCheckState, admissionChecks sets.Set[kueue.AdmissionCheckReference], c clock.Clock) ([]kueue.AdmissionCheckState, bool) {
 	if len(admissionChecks) == 0 {
 		return nil, len(conds) > 0
 	}
 
 	shouldUpdate := false
-	currentChecks := utilslices.ToRefMap(conds, func(c *kueue.AdmissionCheckState) string { return c.Name })
+	currentChecks := utilslices.ToRefMap(conds, func(c *kueue.AdmissionCheckState) kueue.AdmissionCheckReference { return c.Name })
 	for t := range admissionChecks {
 		if _, found := currentChecks[t]; !found {
 			workload.SetAdmissionCheckState(&conds, kueue.AdmissionCheckState{
diff --git a/pkg/controller/jobframework/integrationmanager.go b/pkg/controller/jobframework/integrationmanager.go
index ad9d60459..812404a07 100644
--- a/pkg/controller/jobframework/integrationmanager.go
+++ b/pkg/controller/jobframework/integrationmanager.go
@@ -74,10 +74,6 @@ type IntegrationCallbacks struct {
 	// AddToScheme adds any additional types to the controllers manager's scheme
 	// (this callback is optional)
 	AddToScheme func(s *runtime.Scheme) error
-	// Returns true if the provided owner reference identifies an object
-	// managed by this integration
-	// (this callback is optional)
-	IsManagingObjectsOwner func(ref *metav1.OwnerReference) bool
 	// CanSupportIntegration returns true if the integration meets any additional condition
 	// like the Kubernetes version.
 	CanSupportIntegration func(opts ...Option) (bool, error)
@@ -87,6 +83,21 @@ type IntegrationCallbacks struct {
 	DependencyList []string
 }
 
+func (i *IntegrationCallbacks) getGVK() schema.GroupVersionKind {
+	if i.NewJob != nil {
+		return i.NewJob().GVK()
+	}
+	return i.GVK
+}
+
+func (i *IntegrationCallbacks) matchingGVK(gvk schema.GroupVersionKind) bool {
+	return i.getGVK() == gvk
+}
+
+func (i *IntegrationCallbacks) matchingOwnerReference(ownerRef *metav1.OwnerReference) bool {
+	return ownerReferenceMatchingGVK(ownerRef, i.getGVK())
+}
+
 type integrationManager struct {
 	names                []string
 	integrations         map[string]IntegrationCallbacks
@@ -190,13 +201,12 @@ func (m *integrationManager) getList() []string {
 func (m *integrationManager) getJobTypeForOwner(ownerRef *metav1.OwnerReference) runtime.Object {
 	for jobKey := range m.getEnabledIntegrations() {
 		cbs, found := m.integrations[jobKey]
-		if found && cbs.IsManagingObjectsOwner != nil && cbs.IsManagingObjectsOwner(ownerRef) {
+		if found && cbs.matchingOwnerReference(ownerRef) {
 			return cbs.JobType
 		}
 	}
 	for _, jt := range m.externalIntegrations {
-		apiVersion, kind := jt.GetObjectKind().GroupVersionKind().ToAPIVersionAndKind()
-		if ownerRef.Kind == kind && ownerRef.APIVersion == apiVersion {
+		if ownerReferenceMatchingGVK(ownerRef, jt.GetObjectKind().GroupVersionKind()) {
 			return jt
 		}
 	}
@@ -222,20 +232,15 @@ func (m *integrationManager) checkEnabledListDependencies(enabledSet sets.Set[st
 }
 
 // isOwnerIntegrationEnabled returns true if the provided owner is managed by an enabled integration.
-func (m *integrationManager) isOwnerIntegrationEnabled(owner *metav1.OwnerReference) bool {
-	ownerGV, err := schema.ParseGroupVersion(owner.APIVersion)
-	if err != nil {
-		return false
-	}
-	gvk := ownerGV.WithKind(owner.Kind)
+func (m *integrationManager) isOwnerIntegrationEnabled(ownerRef *metav1.OwnerReference) bool {
 	for jobKey := range m.getEnabledIntegrations() {
 		cbs, found := m.integrations[jobKey]
-		if found && matchingGVK(cbs, gvk) {
+		if found && cbs.matchingOwnerReference(ownerRef) {
 			return true
 		}
 	}
 	for _, jt := range m.externalIntegrations {
-		if jt.GetObjectKind().GroupVersionKind() == gvk {
+		if ownerReferenceMatchingGVK(ownerRef, jt.GetObjectKind().GroupVersionKind()) {
 			return true
 		}
 	}
@@ -292,19 +297,16 @@ func GetIntegration(name string) (IntegrationCallbacks, bool) {
 func GetIntegrationByGVK(gvk schema.GroupVersionKind) (IntegrationCallbacks, bool) {
 	for _, name := range manager.getList() {
 		integration, ok := GetIntegration(name)
-		if ok && matchingGVK(integration, gvk) {
+		if ok && integration.matchingGVK(gvk) {
 			return integration, true
 		}
 	}
 	return IntegrationCallbacks{}, false
 }
 
-func matchingGVK(integration IntegrationCallbacks, gvk schema.GroupVersionKind) bool {
-	if integration.NewJob != nil {
-		return gvk == integration.NewJob().GVK()
-	} else {
-		return gvk == integration.GVK
-	}
+func ownerReferenceMatchingGVK(ownerRef *metav1.OwnerReference, gvk schema.GroupVersionKind) bool {
+	apiVersion, kind := gvk.ToAPIVersionAndKind()
+	return ownerRef.APIVersion == apiVersion && ownerRef.Kind == kind
 }
 
 // GetIntegrationsList returns the list of currently registered frameworks.
@@ -327,15 +329,6 @@ func IsOwnerManagedByKueueForObject(obj client.Object) bool {
 	return false
 }
 
-// IsOwnerIntegrationEnabled returns true if the provided owner is managed by an enabled integration.
-func IsOwnerIntegrationEnabled(owner *metav1.OwnerReference) bool {
-	// This function should be redundant with IsOwnerManagedByKueue, but currently is not.
-	// The difference is caused because the Deployment and StatefulState integrations do not register
-	// an IsManagingObjectsOwner function.  We should attempt to register these integrations properly,
-	// adjust GenericJobReconciler to handle this, and go back to only one function to answer this question.
-	return manager.isOwnerIntegrationEnabled(owner)
-}
-
 // GetEmptyOwnerObject returns an empty object of the owner's type,
 // returns nil if the owner is not manageable by kueue.
 func GetEmptyOwnerObject(owner *metav1.OwnerReference) client.Object {
diff --git a/pkg/controller/jobframework/reconciler.go b/pkg/controller/jobframework/reconciler.go
index 3f7873f8c..061031771 100644
--- a/pkg/controller/jobframework/reconciler.go
+++ b/pkg/controller/jobframework/reconciler.go
@@ -568,7 +568,7 @@ func (r *JobReconciler) recordAdmissionCheckUpdate(wl *kueue.Workload, job Gener
 			if message != "" {
 				message += "; "
 			}
-			message += check.Name + ": " + check.Message
+			message += string(check.Name) + ": " + check.Message
 		}
 	}
 	if message != "" {
diff --git a/pkg/controller/jobs/appwrapper/appwrapper_controller.go b/pkg/controller/jobs/appwrapper/appwrapper_controller.go
index d0db252a1..6869fbcbd 100644
--- a/pkg/controller/jobs/appwrapper/appwrapper_controller.go
+++ b/pkg/controller/jobs/appwrapper/appwrapper_controller.go
@@ -20,12 +20,10 @@ import (
 	"context"
 	"fmt"
 	"strconv"
-	"strings"
 
 	awv1beta2 "github.com/project-codeflare/appwrapper/api/v1beta2"
 	awutils "github.com/project-codeflare/appwrapper/pkg/utils"
 	"k8s.io/apimachinery/pkg/api/meta"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -57,15 +55,14 @@ var (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		NewJob:                 NewJob,
-		GVK:                    gvk,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupAppWrapperWebhook,
-		JobType:                &awv1beta2.AppWrapper{},
-		SetupIndexes:           SetupIndexes,
-		AddToScheme:            awv1beta2.AddToScheme,
-		IsManagingObjectsOwner: isAppWrapper,
-		MultiKueueAdapter:      &multiKueueAdapter{},
+		NewJob:            NewJob,
+		GVK:               gvk,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupAppWrapperWebhook,
+		JobType:           &awv1beta2.AppWrapper{},
+		SetupIndexes:      SetupIndexes,
+		AddToScheme:       awv1beta2.AddToScheme,
+		MultiKueueAdapter: &multiKueueAdapter{},
 	}))
 }
 
@@ -85,10 +82,6 @@ func NewJob() jobframework.GenericJob {
 	return &AppWrapper{}
 }
 
-func isAppWrapper(owner *metav1.OwnerReference) bool {
-	return owner.Kind == awv1beta2.AppWrapperKind && strings.HasPrefix(owner.APIVersion, gvk.Group)
-}
-
 func SetupIndexes(ctx context.Context, indexer client.FieldIndexer) error {
 	return jobframework.SetupWorkloadOwnerIndex(ctx, indexer, gvk)
 }
diff --git a/pkg/controller/jobs/deployment/deployment_controller.go b/pkg/controller/jobs/deployment/deployment_controller.go
index 7cf79b819..bc5779bd5 100644
--- a/pkg/controller/jobs/deployment/deployment_controller.go
+++ b/pkg/controller/jobs/deployment/deployment_controller.go
@@ -20,7 +20,6 @@ import (
 	"context"
 
 	appsv1 "k8s.io/api/apps/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -39,21 +38,16 @@ const (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewReconciler:          jobframework.NewNoopReconcilerFactory(gvk),
-		GVK:                    gvk,
-		SetupWebhook:           SetupWebhook,
-		JobType:                &appsv1.Deployment{},
-		AddToScheme:            appsv1.AddToScheme,
-		DependencyList:         []string{"pod"},
-		IsManagingObjectsOwner: isDeployment,
+		SetupIndexes:   SetupIndexes,
+		NewReconciler:  jobframework.NewNoopReconcilerFactory(gvk),
+		GVK:            gvk,
+		SetupWebhook:   SetupWebhook,
+		JobType:        &appsv1.Deployment{},
+		AddToScheme:    appsv1.AddToScheme,
+		DependencyList: []string{"pod"},
 	}))
 }
 
-func isDeployment(ref *metav1.OwnerReference) bool {
-	return ref.Kind == "Deployment" && ref.APIVersion == "apps/v1"
-}
-
 type Deployment appsv1.Deployment
 
 // +kubebuilder:rbac:groups="apps",resources=deployments,verbs=get;list;watch
diff --git a/pkg/controller/jobs/job/job_controller.go b/pkg/controller/jobs/job/job_controller.go
index 1bb430de3..2ed476f51 100644
--- a/pkg/controller/jobs/job/job_controller.go
+++ b/pkg/controller/jobs/job/job_controller.go
@@ -59,13 +59,12 @@ const (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupWebhook,
-		JobType:                &batchv1.Job{},
-		IsManagingObjectsOwner: isJob,
-		MultiKueueAdapter:      &multiKueueAdapter{},
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupWebhook,
+		JobType:           &batchv1.Job{},
+		MultiKueueAdapter: &multiKueueAdapter{},
 	}))
 }
 
@@ -88,10 +87,6 @@ var NewReconciler = jobframework.NewGenericReconcilerFactory(NewJob, func(b *bui
 	return b.Watches(&kueue.Workload{}, &parentWorkloadHandler{client: c})
 })
 
-func isJob(owner *metav1.OwnerReference) bool {
-	return owner.Kind == "Job" && owner.APIVersion == gvk.GroupVersion().String()
-}
-
 type parentWorkloadHandler struct {
 	client client.Client
 }
diff --git a/pkg/controller/jobs/jobset/jobset_controller.go b/pkg/controller/jobs/jobset/jobset_controller.go
index acae2f01a..805357a8a 100644
--- a/pkg/controller/jobs/jobset/jobset_controller.go
+++ b/pkg/controller/jobs/jobset/jobset_controller.go
@@ -19,7 +19,6 @@ package jobset
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	batchv1 "k8s.io/api/batch/v1"
 	apimeta "k8s.io/apimachinery/pkg/api/meta"
@@ -46,14 +45,13 @@ var (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupJobSetWebhook,
-		JobType:                &jobsetapi.JobSet{},
-		AddToScheme:            jobsetapi.AddToScheme,
-		IsManagingObjectsOwner: isJobSet,
-		MultiKueueAdapter:      &multiKueueAdapter{},
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupJobSetWebhook,
+		JobType:           &jobsetapi.JobSet{},
+		AddToScheme:       jobsetapi.AddToScheme,
+		MultiKueueAdapter: &multiKueueAdapter{},
 	}))
 }
 
@@ -74,10 +72,6 @@ func NewJob() jobframework.GenericJob {
 
 var NewReconciler = jobframework.NewGenericReconcilerFactory(NewJob)
 
-func isJobSet(owner *metav1.OwnerReference) bool {
-	return owner.Kind == "JobSet" && strings.HasPrefix(owner.APIVersion, "jobset.x-k8s.io/v1")
-}
-
 type JobSet jobsetapi.JobSet
 
 var _ jobframework.GenericJob = (*JobSet)(nil)
diff --git a/pkg/controller/jobs/kubeflow/jobs/paddlejob/paddlejob_controller.go b/pkg/controller/jobs/kubeflow/jobs/paddlejob/paddlejob_controller.go
index a57098f61..87e7514c7 100644
--- a/pkg/controller/jobs/kubeflow/jobs/paddlejob/paddlejob_controller.go
+++ b/pkg/controller/jobs/kubeflow/jobs/paddlejob/paddlejob_controller.go
@@ -19,10 +19,8 @@ package paddlejob
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	kftraining "github.com/kubeflow/training-operator/pkg/apis/kubeflow.org/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -50,14 +48,13 @@ var (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupPaddleJobWebhook,
-		JobType:                &kftraining.PaddleJob{},
-		AddToScheme:            kftraining.AddToScheme,
-		IsManagingObjectsOwner: isPaddleJob,
-		MultiKueueAdapter:      kubeflowjob.NewMKAdapter(copyJobSpec, copyJobStatus, getEmptyList, gvk, fromObject),
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupPaddleJobWebhook,
+		JobType:           &kftraining.PaddleJob{},
+		AddToScheme:       kftraining.AddToScheme,
+		MultiKueueAdapter: kubeflowjob.NewMKAdapter(copyJobSpec, copyJobStatus, getEmptyList, gvk, fromObject),
 	}))
 }
 
@@ -80,10 +77,6 @@ var NewReconciler = jobframework.NewGenericReconcilerFactory(func() jobframework
 	return &kubeflowjob.KubeflowJob{KFJobControl: &JobControl{}}
 })
 
-func isPaddleJob(owner *metav1.OwnerReference) bool {
-	return owner.Kind == kftraining.PaddleJobKind && strings.HasPrefix(owner.APIVersion, kftraining.SchemeGroupVersion.Group)
-}
-
 type JobControl kftraining.PaddleJob
 
 var _ kubeflowjob.KFJobControl = (*JobControl)(nil)
diff --git a/pkg/controller/jobs/kubeflow/jobs/pytorchjob/pytorchjob_controller.go b/pkg/controller/jobs/kubeflow/jobs/pytorchjob/pytorchjob_controller.go
index 889e0e2bb..8c8699466 100644
--- a/pkg/controller/jobs/kubeflow/jobs/pytorchjob/pytorchjob_controller.go
+++ b/pkg/controller/jobs/kubeflow/jobs/pytorchjob/pytorchjob_controller.go
@@ -19,10 +19,8 @@ package pytorchjob
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	kftraining "github.com/kubeflow/training-operator/pkg/apis/kubeflow.org/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -50,14 +48,13 @@ var (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupPyTorchJobWebhook,
-		JobType:                &kftraining.PyTorchJob{},
-		AddToScheme:            kftraining.AddToScheme,
-		IsManagingObjectsOwner: isPyTorchJob,
-		MultiKueueAdapter:      kubeflowjob.NewMKAdapter(copyJobSpec, copyJobStatus, getEmptyList, gvk, fromObject),
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupPyTorchJobWebhook,
+		JobType:           &kftraining.PyTorchJob{},
+		AddToScheme:       kftraining.AddToScheme,
+		MultiKueueAdapter: kubeflowjob.NewMKAdapter(copyJobSpec, copyJobStatus, getEmptyList, gvk, fromObject),
 	}))
 }
 
@@ -80,10 +77,6 @@ var NewReconciler = jobframework.NewGenericReconcilerFactory(func() jobframework
 	return &kubeflowjob.KubeflowJob{KFJobControl: &JobControl{}}
 })
 
-func isPyTorchJob(owner *metav1.OwnerReference) bool {
-	return owner.Kind == kftraining.PyTorchJobKind && strings.HasPrefix(owner.APIVersion, kftraining.SchemeGroupVersion.Group)
-}
-
 type JobControl kftraining.PyTorchJob
 
 var _ kubeflowjob.KFJobControl = (*JobControl)(nil)
diff --git a/pkg/controller/jobs/kubeflow/jobs/tfjob/tfjob_controller.go b/pkg/controller/jobs/kubeflow/jobs/tfjob/tfjob_controller.go
index 916264421..672a800ef 100644
--- a/pkg/controller/jobs/kubeflow/jobs/tfjob/tfjob_controller.go
+++ b/pkg/controller/jobs/kubeflow/jobs/tfjob/tfjob_controller.go
@@ -19,10 +19,8 @@ package tfjob
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	kftraining "github.com/kubeflow/training-operator/pkg/apis/kubeflow.org/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -50,14 +48,13 @@ var (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupTFJobWebhook,
-		JobType:                &kftraining.TFJob{},
-		AddToScheme:            kftraining.AddToScheme,
-		IsManagingObjectsOwner: isTFJob,
-		MultiKueueAdapter:      kubeflowjob.NewMKAdapter(copyJobSpec, copyJobStatus, getEmptyList, gvk, fromObject),
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupTFJobWebhook,
+		JobType:           &kftraining.TFJob{},
+		AddToScheme:       kftraining.AddToScheme,
+		MultiKueueAdapter: kubeflowjob.NewMKAdapter(copyJobSpec, copyJobStatus, getEmptyList, gvk, fromObject),
 	}))
 }
 
@@ -80,10 +77,6 @@ var NewReconciler = jobframework.NewGenericReconcilerFactory(func() jobframework
 	return &kubeflowjob.KubeflowJob{KFJobControl: &JobControl{}}
 })
 
-func isTFJob(owner *metav1.OwnerReference) bool {
-	return owner.Kind == kftraining.TFJobKind && strings.HasPrefix(owner.APIVersion, kftraining.SchemeGroupVersion.Group)
-}
-
 type JobControl kftraining.TFJob
 
 var _ kubeflowjob.KFJobControl = (*JobControl)(nil)
diff --git a/pkg/controller/jobs/kubeflow/jobs/xgboostjob/xgboostjob_controller.go b/pkg/controller/jobs/kubeflow/jobs/xgboostjob/xgboostjob_controller.go
index 085d88c35..efb147d80 100644
--- a/pkg/controller/jobs/kubeflow/jobs/xgboostjob/xgboostjob_controller.go
+++ b/pkg/controller/jobs/kubeflow/jobs/xgboostjob/xgboostjob_controller.go
@@ -19,10 +19,8 @@ package xgboostjob
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	kftraining "github.com/kubeflow/training-operator/pkg/apis/kubeflow.org/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -50,14 +48,13 @@ var (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupXGBoostJobWebhook,
-		JobType:                &kftraining.XGBoostJob{},
-		AddToScheme:            kftraining.AddToScheme,
-		IsManagingObjectsOwner: isXGBoostJob,
-		MultiKueueAdapter:      kubeflowjob.NewMKAdapter(copyJobSpec, copyJobStatus, getEmptyList, gvk, fromObject),
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupXGBoostJobWebhook,
+		JobType:           &kftraining.XGBoostJob{},
+		AddToScheme:       kftraining.AddToScheme,
+		MultiKueueAdapter: kubeflowjob.NewMKAdapter(copyJobSpec, copyJobStatus, getEmptyList, gvk, fromObject),
 	}))
 }
 
@@ -80,10 +77,6 @@ var NewReconciler = jobframework.NewGenericReconcilerFactory(func() jobframework
 	return &kubeflowjob.KubeflowJob{KFJobControl: &JobControl{}}
 })
 
-func isXGBoostJob(owner *metav1.OwnerReference) bool {
-	return owner.Kind == kftraining.XGBoostJobKind && strings.HasPrefix(owner.APIVersion, kftraining.SchemeGroupVersion.Group)
-}
-
 type JobControl kftraining.XGBoostJob
 
 var _ kubeflowjob.KFJobControl = (*JobControl)(nil)
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_controller.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_controller.go
index dffce5d29..006da4321 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_controller.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_controller.go
@@ -18,9 +18,7 @@ package leaderworkerset
 
 import (
 	"context"
-	"strings"
 
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -47,7 +45,6 @@ func init() {
 		JobType:                  &leaderworkersetv1.LeaderWorkerSet{},
 		AddToScheme:              leaderworkersetv1.AddToScheme,
 		DependencyList:           []string{"pod"},
-		IsManagingObjectsOwner:   isLeaderWorkerSet,
 		GVK:                      gvk,
 	}))
 }
@@ -58,10 +55,6 @@ func fromObject(o runtime.Object) *LeaderWorkerSet {
 	return (*LeaderWorkerSet)(o.(*leaderworkersetv1.LeaderWorkerSet))
 }
 
-func isLeaderWorkerSet(ref *metav1.OwnerReference) bool {
-	return ref.Kind == "LeaderWorkerSet" && strings.HasPrefix(ref.APIVersion, "leaderworkerset.x-k8s.io/v1")
-}
-
 func (lws *LeaderWorkerSet) Object() client.Object {
 	return (*leaderworkersetv1.LeaderWorkerSet)(lws)
 }
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler.go
index d39814fef..29d89c12b 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler.go
@@ -19,8 +19,11 @@ package leaderworkerset
 import (
 	"context"
 	"fmt"
+	"maps"
+	"slices"
 
 	"github.com/go-logr/logr"
+	"golang.org/x/sync/errgroup"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/labels"
 	"k8s.io/client-go/tools/record"
@@ -28,15 +31,19 @@ import (
 	"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"
 	"sigs.k8s.io/controller-runtime/pkg/event"
 	"sigs.k8s.io/controller-runtime/pkg/predicate"
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 	leaderworkersetv1 "sigs.k8s.io/lws/api/leaderworkerset/v1"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
+	"sigs.k8s.io/kueue/pkg/controller/core/indexer"
 	"sigs.k8s.io/kueue/pkg/controller/jobframework"
 	podcontroller "sigs.k8s.io/kueue/pkg/controller/jobs/pod"
 	"sigs.k8s.io/kueue/pkg/features"
+	"sigs.k8s.io/kueue/pkg/util/parallelize"
+	utilslices "sigs.k8s.io/kueue/pkg/util/slices"
 	"sigs.k8s.io/kueue/pkg/workload"
 )
 
@@ -92,7 +99,30 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco
 	log := ctrl.LoggerFrom(ctx)
 	log.V(2).Info("Reconcile LeaderWorkerSet")
 
-	err = r.createPrebuiltWorkloadsIfNotExist(ctx, lws)
+	wlList := &kueue.WorkloadList{}
+	if err := r.client.List(ctx, wlList, client.InNamespace(lws.GetNamespace()),
+		client.MatchingFields{indexer.OwnerReferenceUID: string(lws.GetUID())},
+	); err != nil {
+		return ctrl.Result{}, err
+	}
+
+	toCreate, toFinalize := r.filterWorkloads(lws, wlList.Items)
+
+	eg, ctx := errgroup.WithContext(ctx)
+
+	eg.Go(func() error {
+		return parallelize.Until(ctx, len(toCreate), func(i int) error {
+			return r.createPrebuiltWorkload(ctx, lws, toCreate[i])
+		})
+	})
+
+	eg.Go(func() error {
+		return parallelize.Until(ctx, len(toFinalize), func(i int) error {
+			return r.removeOwnerReference(ctx, lws, toFinalize[i])
+		})
+	})
+
+	err = eg.Wait()
 	if err != nil {
 		return ctrl.Result{}, err
 	}
@@ -100,28 +130,38 @@ func (r *Reconciler) Reconcile(ctx context.Context, req reconcile.Request) (reco
 	return ctrl.Result{}, nil
 }
 
-func (r *Reconciler) createPrebuiltWorkloadsIfNotExist(ctx context.Context, lws *leaderworkersetv1.LeaderWorkerSet) error {
-	replicas := ptr.Deref(lws.Spec.Replicas, 1)
+// filterWorkloads compares the desired state in a LeaderWorkerSet with existing workloads,
+// identifying workloads to create and those to finalize.
+//
+// It takes a LeaderWorkerSet and a slice of existing Workload objects as input and returns:
+// 1. A slice of workload names that need to be created
+// 2. A slice of Workload pointers that need to be finalized
+func (r *Reconciler) filterWorkloads(lws *leaderworkersetv1.LeaderWorkerSet, existingWorkloads []kueue.Workload) ([]string, []*kueue.Workload) {
+	var (
+		toCreate   []string
+		toFinalize = utilslices.ToRefMap(existingWorkloads, func(e *kueue.Workload) string {
+			return e.Name
+		})
+		replicas = ptr.Deref(lws.Spec.Replicas, 1)
+	)
+
 	for i := int32(0); i < replicas; i++ {
-		if err := r.createPrebuiltWorkloadIfNotExist(ctx, lws, i); err != nil {
-			return err
+		workloadName := GetWorkloadName(lws.UID, lws.Name, fmt.Sprint(i))
+		if _, ok := toFinalize[workloadName]; ok {
+			delete(toFinalize, workloadName)
+		} else {
+			toCreate = append(toCreate, workloadName)
 		}
 	}
-	return nil
+
+	return toCreate, slices.Collect(maps.Values(toFinalize))
 }
 
-func (r *Reconciler) createPrebuiltWorkloadIfNotExist(ctx context.Context, lws *leaderworkersetv1.LeaderWorkerSet, index int32) error {
-	wl := &kueue.Workload{}
-	err := r.client.Get(ctx, client.ObjectKey{Name: GetWorkloadName(lws.UID, lws.Name, fmt.Sprint(index)), Namespace: lws.Namespace}, wl)
-	// Ignore if the Workload already exists or an error occurs.
-	if err == nil || client.IgnoreNotFound(err) != nil {
+func (r *Reconciler) createPrebuiltWorkload(ctx context.Context, lws *leaderworkersetv1.LeaderWorkerSet, workloadName string) error {
+	createdWorkload, err := r.constructWorkload(lws, workloadName)
+	if err != nil {
 		return err
 	}
-	return r.createPrebuiltWorkload(ctx, lws, index)
-}
-
-func (r *Reconciler) createPrebuiltWorkload(ctx context.Context, lws *leaderworkersetv1.LeaderWorkerSet, index int32) error {
-	createdWorkload := r.constructWorkload(lws, index)
 
 	priorityClassName, source, p, err := jobframework.ExtractPriority(ctx, r.client, lws, createdWorkload.Spec.PodSets, nil)
 	if err != nil {
@@ -143,8 +183,12 @@ func (r *Reconciler) createPrebuiltWorkload(ctx context.Context, lws *leaderwork
 	return nil
 }
 
-func (r *Reconciler) constructWorkload(lws *leaderworkersetv1.LeaderWorkerSet, index int32) *kueue.Workload {
-	return podcontroller.NewGroupWorkload(GetWorkloadName(lws.UID, lws.Name, fmt.Sprint(index)), lws, r.podSets(lws), r.labelKeysToCopy)
+func (r *Reconciler) constructWorkload(lws *leaderworkersetv1.LeaderWorkerSet, workloadName string) (*kueue.Workload, error) {
+	createdWorkload := podcontroller.NewGroupWorkload(workloadName, lws, r.podSets(lws), r.labelKeysToCopy)
+	if err := controllerutil.SetOwnerReference(lws, createdWorkload, r.client.Scheme()); err != nil {
+		return nil, err
+	}
+	return createdWorkload, nil
 }
 
 func (r *Reconciler) podSets(lws *leaderworkersetv1.LeaderWorkerSet) []kueue.PodSet {
@@ -198,6 +242,14 @@ func (r *Reconciler) podSets(lws *leaderworkersetv1.LeaderWorkerSet) []kueue.Pod
 	return podSets
 }
 
+func (r *Reconciler) removeOwnerReference(ctx context.Context, lws *leaderworkersetv1.LeaderWorkerSet, wl *kueue.Workload) error {
+	err := controllerutil.RemoveOwnerReference(lws, wl, r.client.Scheme())
+	if err != nil {
+		return err
+	}
+	return r.client.Update(ctx, wl)
+}
+
 var _ predicate.Predicate = (*Reconciler)(nil)
 
 func (r *Reconciler) Generic(event.GenericEvent) bool {
diff --git a/pkg/controller/jobs/mpijob/mpijob_controller.go b/pkg/controller/jobs/mpijob/mpijob_controller.go
index 2b0c0f95d..e15b26c89 100644
--- a/pkg/controller/jobs/mpijob/mpijob_controller.go
+++ b/pkg/controller/jobs/mpijob/mpijob_controller.go
@@ -19,11 +19,9 @@ package mpijob
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	kfmpi "github.com/kubeflow/mpi-operator/pkg/apis/kubeflow/v2beta1"
 	corev1 "k8s.io/api/core/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -45,14 +43,13 @@ var (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupMPIJobWebhook,
-		JobType:                &kfmpi.MPIJob{},
-		AddToScheme:            kfmpi.AddToScheme,
-		IsManagingObjectsOwner: isMPIJob,
-		MultiKueueAdapter:      &multiKueueAdapter{},
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupMPIJobWebhook,
+		JobType:           &kfmpi.MPIJob{},
+		AddToScheme:       kfmpi.AddToScheme,
+		MultiKueueAdapter: &multiKueueAdapter{},
 	}))
 }
 
@@ -73,10 +70,6 @@ func NewJob() jobframework.GenericJob {
 
 var NewReconciler = jobframework.NewGenericReconcilerFactory(NewJob)
 
-func isMPIJob(owner *metav1.OwnerReference) bool {
-	return owner.Kind == "MPIJob" && strings.HasPrefix(owner.APIVersion, kfmpi.SchemeGroupVersion.Group)
-}
-
 type MPIJob kfmpi.MPIJob
 
 var _ jobframework.GenericJob = (*MPIJob)(nil)
diff --git a/pkg/controller/jobs/pod/pod_controller.go b/pkg/controller/jobs/pod/pod_controller.go
index 941c0bf49..846f87f14 100644
--- a/pkg/controller/jobs/pod/pod_controller.go
+++ b/pkg/controller/jobs/pod/pod_controller.go
@@ -90,20 +90,15 @@ var (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupWebhook,
-		JobType:                &corev1.Pod{},
-		MultiKueueAdapter:      &multiKueueAdapter{},
-		IsManagingObjectsOwner: isPod,
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupWebhook,
+		JobType:           &corev1.Pod{},
+		MultiKueueAdapter: &multiKueueAdapter{},
 	}))
 }
 
-func isPod(ref *metav1.OwnerReference) bool {
-	return ref.Kind == "Pod" && ref.APIVersion == "v1"
-}
-
 // +kubebuilder:rbac:groups=scheduling.k8s.io,resources=priorityclasses,verbs=list;get;watch
 // +kubebuilder:rbac:groups="",resources=events,verbs=create;watch;update;patch
 // +kubebuilder:rbac:groups="",resources=pods,verbs=get;list;watch;update;patch;delete
@@ -345,6 +340,10 @@ func (p *Pod) RestorePodSetsInfo(_ []podset.PodSetInfo) bool {
 // Finished means whether the job is completed/failed or not,
 // condition represents the workload finished condition.
 func (p *Pod) Finished() (message string, success, finished bool) {
+	if p.isServing() {
+		return "", true, false
+	}
+
 	finished = true
 	success = true
 
diff --git a/pkg/controller/jobs/raycluster/raycluster_controller.go b/pkg/controller/jobs/raycluster/raycluster_controller.go
index 5da47add1..f4a2f1353 100644
--- a/pkg/controller/jobs/raycluster/raycluster_controller.go
+++ b/pkg/controller/jobs/raycluster/raycluster_controller.go
@@ -19,11 +19,9 @@ package raycluster
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
 	rayutils "github.com/ray-project/kuberay/ray-operator/controllers/ray/utils"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -48,14 +46,13 @@ const (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupRayClusterWebhook,
-		JobType:                &rayv1.RayCluster{},
-		AddToScheme:            rayv1.AddToScheme,
-		IsManagingObjectsOwner: isRayCluster,
-		MultiKueueAdapter:      &multiKueueAdapter{},
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupRayClusterWebhook,
+		JobType:           &rayv1.RayCluster{},
+		AddToScheme:       rayv1.AddToScheme,
+		MultiKueueAdapter: &multiKueueAdapter{},
 	}))
 }
 
@@ -209,10 +206,6 @@ func GetWorkloadNameForRayCluster(jobName string, jobUID types.UID) string {
 	return jobframework.GetWorkloadNameForOwnerWithGVK(jobName, jobUID, gvk)
 }
 
-func isRayCluster(owner *metav1.OwnerReference) bool {
-	return owner.Kind == "RayCluster" && strings.HasPrefix(owner.APIVersion, "ray.io/v1")
-}
-
 func fromObject(o runtime.Object) *RayCluster {
 	return (*RayCluster)(o.(*rayv1.RayCluster))
 }
diff --git a/pkg/controller/jobs/rayjob/rayjob_controller.go b/pkg/controller/jobs/rayjob/rayjob_controller.go
index 6743045ce..eec0bfef7 100644
--- a/pkg/controller/jobs/rayjob/rayjob_controller.go
+++ b/pkg/controller/jobs/rayjob/rayjob_controller.go
@@ -19,13 +19,11 @@ package rayjob
 import (
 	"context"
 	"fmt"
-	"strings"
 
 	rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1"
 	rayutils "github.com/ray-project/kuberay/ray-operator/controllers/ray/utils"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	"k8s.io/apimachinery/pkg/types"
@@ -50,14 +48,13 @@ const (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewJob:                 NewJob,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupRayJobWebhook,
-		JobType:                &rayv1.RayJob{},
-		AddToScheme:            rayv1.AddToScheme,
-		IsManagingObjectsOwner: isRayJob,
-		MultiKueueAdapter:      &multiKueueAdapter{},
+		SetupIndexes:      SetupIndexes,
+		NewJob:            NewJob,
+		NewReconciler:     NewReconciler,
+		SetupWebhook:      SetupRayJobWebhook,
+		JobType:           &rayv1.RayJob{},
+		AddToScheme:       rayv1.AddToScheme,
+		MultiKueueAdapter: &multiKueueAdapter{},
 	}))
 }
 
@@ -261,10 +258,6 @@ func GetWorkloadNameForRayJob(jobName string, jobUID types.UID) string {
 	return jobframework.GetWorkloadNameForOwnerWithGVK(jobName, jobUID, gvk)
 }
 
-func isRayJob(owner *metav1.OwnerReference) bool {
-	return owner.Kind == "RayJob" && strings.HasPrefix(owner.APIVersion, "ray.io/v1")
-}
-
 // getSubmitterTemplate returns the PodTemplteSpec of the submitter Job used for RayJob when submissionMode=K8sJobMode
 func getSubmitterTemplate(rayJob *RayJob) *corev1.PodTemplateSpec {
 	if rayJob.Spec.SubmitterPodTemplate != nil {
diff --git a/pkg/controller/jobs/statefulset/statefulset_controller.go b/pkg/controller/jobs/statefulset/statefulset_controller.go
index 502e922dc..0039a747c 100644
--- a/pkg/controller/jobs/statefulset/statefulset_controller.go
+++ b/pkg/controller/jobs/statefulset/statefulset_controller.go
@@ -20,7 +20,6 @@ import (
 	"context"
 
 	appsv1 "k8s.io/api/apps/v1"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/runtime/schema"
 	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
@@ -39,21 +38,16 @@ const (
 
 func init() {
 	utilruntime.Must(jobframework.RegisterIntegration(FrameworkName, jobframework.IntegrationCallbacks{
-		SetupIndexes:           SetupIndexes,
-		NewReconciler:          NewReconciler,
-		SetupWebhook:           SetupWebhook,
-		JobType:                &appsv1.StatefulSet{},
-		AddToScheme:            appsv1.AddToScheme,
-		DependencyList:         []string{"pod"},
-		GVK:                    gvk,
-		IsManagingObjectsOwner: isStatefulSet,
+		SetupIndexes:   SetupIndexes,
+		NewReconciler:  NewReconciler,
+		SetupWebhook:   SetupWebhook,
+		JobType:        &appsv1.StatefulSet{},
+		AddToScheme:    appsv1.AddToScheme,
+		DependencyList: []string{"pod"},
+		GVK:            gvk,
 	}))
 }
 
-func isStatefulSet(ref *metav1.OwnerReference) bool {
-	return ref.Kind == "StatefulSet" && ref.APIVersion == "apps/v1"
-}
-
 type StatefulSet appsv1.StatefulSet
 
 func fromObject(o runtime.Object) *StatefulSet {
diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go
index 4aa8d9842..2c9ca6c1b 100644
--- a/pkg/features/kube_features.go
+++ b/pkg/features/kube_features.go
@@ -116,18 +116,6 @@ const (
 	// all currently available ResourceFlavors for the LocalQueue.
 	ExposeFlavorsInLocalQueue featuregate.Feature = "ExposeFlavorsInLocalQueue"
 
-	// owner: @mszadkow
-	// kep: https://github.com/kubernetes-sigs/kueue/issues/3094
-	//
-	// Enable additional AdmissionCheck validation rules that will appear in status conditions.
-	AdmissionCheckValidationRules featuregate.Feature = "AdmissionCheckValidationRules"
-
-	// owner: @pbundyra
-	// kep: https://github.com/kubernetes-sigs/kueue/tree/main/keps/1136-provisioning-request-support
-	//
-	// Workloads keeps allocated quota and preserves QuotaReserved=True when ProvisioningRequest fails
-	KeepQuotaForProvReqRetry featuregate.Feature = "KeepQuotaForProvReqRetry"
-
 	// owner: @dgrove-oss
 	// kep: https://github.com/kubernetes-sigs/kueue/tree/main/keps/3589-manage-jobs-selectively
 	//
@@ -234,12 +222,6 @@ var defaultVersionedFeatureGates = map[featuregate.Feature]featuregate.Versioned
 	ExposeFlavorsInLocalQueue: {
 		{Version: version.MustParse("0.9"), Default: true, PreRelease: featuregate.Beta},
 	},
-	AdmissionCheckValidationRules: {
-		{Version: version.MustParse("0.9"), Default: false, PreRelease: featuregate.Deprecated},
-	},
-	KeepQuotaForProvReqRetry: {
-		{Version: version.MustParse("0.9"), Default: false, PreRelease: featuregate.Deprecated},
-	},
 	ManagedJobsNamespaceSelector: {
 		{Version: version.MustParse("0.10"), Default: true, PreRelease: featuregate.Beta},
 	},
@@ -259,8 +241,7 @@ var defaultVersionedFeatureGates = map[featuregate.Feature]featuregate.Versioned
 		{Version: version.MustParse("0.11"), Default: false, PreRelease: featuregate.Deprecated},
 	},
 	HierarchicalCohorts: {
-		{Version: version.MustParse("0.7"), Default: false, PreRelease: featuregate.Alpha},
-		{Version: version.MustParse("0.8"), Default: true, PreRelease: featuregate.Beta},
+		{Version: version.MustParse("0.11"), Default: true, PreRelease: featuregate.Beta},
 	},
 }
 
diff --git a/pkg/scheduler/flavorassigner/flavorassigner.go b/pkg/scheduler/flavorassigner/flavorassigner.go
index 5fd15714e..0000fd4ce 100644
--- a/pkg/scheduler/flavorassigner/flavorassigner.go
+++ b/pkg/scheduler/flavorassigner/flavorassigner.go
@@ -37,12 +37,15 @@ import (
 	"sigs.k8s.io/kueue/pkg/cache"
 	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/resources"
+	"sigs.k8s.io/kueue/pkg/scheduler/preemption/classical"
 	"sigs.k8s.io/kueue/pkg/workload"
 )
 
 type Assignment struct {
-	PodSets   []PodSetAssignment
-	Borrowing bool
+	PodSets []PodSetAssignment
+	// Borrowing is the height of the smallest cohort tree that fits
+	// the additional Usage. It equals to 0 if no borrowing is required.
+	Borrowing int
 	LastState workload.AssignmentClusterQueueState
 
 	// Usage is the accumulated Usage of resources as pod sets get
@@ -86,7 +89,7 @@ func (a *Assignment) computeTASUsage() workload.TASUsage {
 }
 
 // Borrows return whether assignment requires borrowing.
-func (a *Assignment) Borrows() bool {
+func (a *Assignment) Borrows() int {
 	return a.Borrowing
 }
 
@@ -331,7 +334,7 @@ type FlavorAssignment struct {
 	Name           kueue.ResourceFlavorReference
 	Mode           FlavorAssignmentMode
 	TriedFlavorIdx int
-	borrow         bool
+	borrow         int
 }
 
 type preemptionOracle interface {
@@ -481,8 +484,8 @@ func (a *Assignment) append(requests resources.Requests, psAssignment *PodSetAss
 	flavorIdx := make(map[corev1.ResourceName]int, len(psAssignment.Flavors))
 	a.PodSets = append(a.PodSets, *psAssignment)
 	for resource, flvAssignment := range psAssignment.Flavors {
-		if flvAssignment.borrow {
-			a.Borrowing = true
+		if flvAssignment.borrow > a.Borrowing {
+			a.Borrowing = flvAssignment.borrow
 		}
 		fr := resources.FlavorResource{Flavor: flvAssignment.Name, Resource: resource}
 		a.Usage.Quota[fr] += requests[resource]
@@ -568,7 +571,7 @@ func (a *FlavorAssigner) findFlavorForPodSetResource(
 			if mode < representativeMode {
 				representativeMode = mode
 			}
-			needsBorrowing = needsBorrowing || borrow
+			needsBorrowing = needsBorrowing || (borrow > 0)
 			if representativeMode == noFit {
 				// The flavor doesn't fit, no need to check other resources.
 				break
@@ -689,10 +692,9 @@ func flavorSelector(spec *corev1.PodSpec, allowedKeys sets.Set[string]) nodeaffi
 // if borrowing is required when preempting.
 // If the flavor doesn't satisfy limits immediately (when waiting or preemption
 // could help), it returns a Status with reasons.
-func (a *FlavorAssigner) fitsResourceQuota(log logr.Logger, fr resources.FlavorResource, val int64, rQuota cache.ResourceQuota) (granularMode, bool, *Status) {
+func (a *FlavorAssigner) fitsResourceQuota(log logr.Logger, fr resources.FlavorResource, val int64, rQuota cache.ResourceQuota) (granularMode, int, *Status) {
 	var status Status
 
-	borrow := a.cq.BorrowingWith(fr, val) && a.cq.HasParent()
 	available := a.cq.Available(fr)
 	maxCapacity := a.cq.PotentialAvailable(fr)
 
@@ -700,9 +702,10 @@ func (a *FlavorAssigner) fitsResourceQuota(log logr.Logger, fr resources.FlavorR
 	if val > maxCapacity {
 		status.appendf("insufficient quota for %s in flavor %s, request > maximum capacity (%s > %s)",
 			fr.Resource, fr.Flavor, resources.ResourceQuantityString(fr.Resource, val), resources.ResourceQuantityString(fr.Resource, maxCapacity))
-		return noFit, false, &status
+		return noFit, 0, &status
 	}
 
+	borrow, mayReclaimInHierarchy := classical.FindHeightOfLowestSubtreeThatFits(a.cq, fr, val)
 	// Fit
 	if val <= available {
 		return fit, borrow, nil
@@ -710,7 +713,8 @@ func (a *FlavorAssigner) fitsResourceQuota(log logr.Logger, fr resources.FlavorR
 
 	// Check if preemption is possible
 	mode := noFit
-	if val <= rQuota.Nominal {
+	// For single-level hierarchies, mayReclaimInHierarchy = true iff val <= rQuota.Nominal
+	if val <= rQuota.Nominal || mayReclaimInHierarchy {
 		mode = preempt
 		if a.oracle.IsReclaimPossible(log, a.cq, *a.wl, fr, val) {
 			mode = reclaim
diff --git a/pkg/scheduler/preemption/classical/candidate_generator.go b/pkg/scheduler/preemption/classical/candidate_generator.go
new file mode 100644
index 000000000..c782a5520
--- /dev/null
+++ b/pkg/scheduler/preemption/classical/candidate_generator.go
@@ -0,0 +1,160 @@
+/*
+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 classical
+
+import (
+	"sort"
+	"time"
+
+	"k8s.io/apimachinery/pkg/api/meta"
+	"k8s.io/apimachinery/pkg/util/sets"
+	"k8s.io/utils/clock"
+
+	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
+	"sigs.k8s.io/kueue/pkg/cache"
+	"sigs.k8s.io/kueue/pkg/resources"
+	"sigs.k8s.io/kueue/pkg/workload"
+)
+
+type candidateIterator struct {
+	candidates                        []*candidateElem
+	runIndex                          int
+	frsNeedPreemption                 sets.Set[resources.FlavorResource]
+	snapshot                          *cache.Snapshot
+	NoCandidateFromOtherQueues        bool
+	NoCandidateForHierarchicalReclaim bool
+	hierarchicalReclaimCtx            *HierarchicalPreemptionCtx
+}
+
+type candidateElem struct {
+	wl *workload.Info
+	// lca of this queue and cq (queue to which the new workload is submitted)
+	lca *cache.CohortSnapshot
+	// candidates above priority threshold cannot be preempted if at the same time
+	// cq would borrow from other queues/cohorts
+	preemptionVariant preemptionVariant
+}
+
+// Need a separate function for candidateElem data type
+// in the future we will modify the ordering to take into
+// account the distance in the cohort hierarchy tree
+func candidateElemsOrdering(candidates []*candidateElem, cq kueue.ClusterQueueReference, now time.Time, ordering func([]*workload.Info, kueue.ClusterQueueReference, time.Time) func(int, int) bool) func(int, int) bool {
+	// Adapt the candidatesOrdering function to work with candidateElem
+	adaptedOrdering := func(i, j int) bool {
+		a := candidates[i].wl
+		b := candidates[j].wl
+		return ordering([]*workload.Info{a, b}, cq, now)(0, 1)
+	}
+	return adaptedOrdering
+}
+
+func WorkloadUsesResources(wl *workload.Info, frsNeedPreemption sets.Set[resources.FlavorResource]) bool {
+	for _, ps := range wl.TotalRequests {
+		for res, flv := range ps.Flavors {
+			if frsNeedPreemption.Has(resources.FlavorResource{Flavor: flv, Resource: res}) {
+				return true
+			}
+		}
+	}
+	return false
+}
+
+// assume a prefix of the elements has condition WorkloadEvicted = true
+func splitEvicted(workloads []*candidateElem) ([]*candidateElem, []*candidateElem) {
+	firstFalse := sort.Search(len(workloads), func(i int) bool {
+		return !meta.IsStatusConditionTrue(workloads[i].wl.Obj.Status.Conditions, kueue.WorkloadEvicted)
+	})
+	return workloads[:firstFalse], workloads[firstFalse:]
+}
+
+// NewCandidateIterator creates a new iterator that yields candidate workloads for preemption
+// The iterator can be used to perform two independent runs over the list of candidates:
+// with and without borrowing. The runs are independent which means that the same candidates
+// might be returned for both, but note that the candidates with borrrowing are a subset of
+// candidates without borrowing.
+func NewCandidateIterator(hierarchicalReclaimCtx *HierarchicalPreemptionCtx, frsNeedPreemption sets.Set[resources.FlavorResource], snapshot *cache.Snapshot, clock clock.Clock, ordering func([]*workload.Info, kueue.ClusterQueueReference, time.Time) func(int, int) bool) *candidateIterator {
+	sameQueueCandidates := collectSameQueueCandidates(hierarchicalReclaimCtx)
+	hierarchyCandidates, priorityCandidates := collectCandidatesForHierarchicalReclaim(hierarchicalReclaimCtx)
+	sort.Slice(sameQueueCandidates, candidateElemsOrdering(sameQueueCandidates, hierarchicalReclaimCtx.Cq.Name, clock.Now(), ordering))
+	sort.Slice(priorityCandidates, candidateElemsOrdering(priorityCandidates, hierarchicalReclaimCtx.Cq.Name, clock.Now(), ordering))
+	sort.Slice(hierarchyCandidates, candidateElemsOrdering(hierarchyCandidates, hierarchicalReclaimCtx.Cq.Name, clock.Now(), ordering))
+	evictedHierarchicalReclaimCandidates, nonEvictedHierarchicalReclaimCandidates := splitEvicted(hierarchyCandidates)
+	evictedSTCandidates, nonEvictedSTCandidates := splitEvicted(priorityCandidates)
+	evictedSameQueueCandidates, nonEvictedSameQueueCandidates := splitEvicted(sameQueueCandidates)
+	allCandidates := make([]*candidateElem, 0, len(hierarchyCandidates)+len(priorityCandidates)+len(sameQueueCandidates))
+	allCandidates = append(allCandidates, evictedHierarchicalReclaimCandidates...)
+	allCandidates = append(allCandidates, evictedSTCandidates...)
+	allCandidates = append(allCandidates, evictedSameQueueCandidates...)
+	allCandidates = append(allCandidates, nonEvictedHierarchicalReclaimCandidates...)
+	allCandidates = append(allCandidates, nonEvictedSTCandidates...)
+	allCandidates = append(allCandidates, nonEvictedSameQueueCandidates...)
+	return &candidateIterator{
+		runIndex:                          0,
+		frsNeedPreemption:                 frsNeedPreemption,
+		snapshot:                          snapshot,
+		candidates:                        allCandidates,
+		NoCandidateFromOtherQueues:        len(hierarchyCandidates) == 0 && len(priorityCandidates) == 0,
+		NoCandidateForHierarchicalReclaim: len(hierarchyCandidates) == 0,
+		hierarchicalReclaimCtx:            hierarchicalReclaimCtx,
+	}
+}
+
+// Next allows to iterate over the ordered sequence of candidates, with the reason
+// for eviction returned together with a candidate.
+func (c *candidateIterator) Next(borrow bool) (*workload.Info, string) {
+	if c.runIndex >= len(c.candidates) {
+		return nil, ""
+	}
+	candidate := c.candidates[c.runIndex]
+	c.runIndex++
+	if !c.candidateIsValid(candidate, borrow) {
+		return c.Next(borrow)
+	}
+	return candidate.wl, candidate.preemptionVariant.PreemptionReason()
+}
+
+// candidateIsValid checks if candidate is valid,
+// as eg. some candidates can only be considered without borrowing
+// Also, preemption of candidates might invalidate other candidates
+func (c *candidateIterator) candidateIsValid(candidate *candidateElem, borrow bool) bool {
+	if c.hierarchicalReclaimCtx.Cq.Name == candidate.wl.ClusterQueue {
+		return true
+	}
+	if borrow && candidate.preemptionVariant == ReclaimWithoutBorrowing {
+		return false
+	}
+	cq := c.snapshot.ClusterQueue(candidate.wl.ClusterQueue)
+	if cache.IsWithinNominalInResources(cq, c.frsNeedPreemption) {
+		return false
+	}
+	// we don't go all the way to the root but only to the lca node
+	for node := range cq.PathParentToRoot() {
+		if node == candidate.lca {
+			break
+		}
+		if cache.IsWithinNominalInResources(node, c.frsNeedPreemption) {
+			return false
+		}
+	}
+	return true
+}
+
+// Reset moves the candidate iterator back to the starting position.
+// It is required to reset the iterator before each run.
+func (c *candidateIterator) Reset() {
+	c.runIndex = 0
+}
diff --git a/pkg/scheduler/preemption/classical/hierarchical_preemption.go b/pkg/scheduler/preemption/classical/hierarchical_preemption.go
new file mode 100644
index 000000000..80d0aa17f
--- /dev/null
+++ b/pkg/scheduler/preemption/classical/hierarchical_preemption.go
@@ -0,0 +1,234 @@
+/*
+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 classical
+
+import (
+	"k8s.io/apimachinery/pkg/util/sets"
+
+	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
+	"sigs.k8s.io/kueue/pkg/cache"
+	"sigs.k8s.io/kueue/pkg/resources"
+	"sigs.k8s.io/kueue/pkg/util/priority"
+	"sigs.k8s.io/kueue/pkg/workload"
+)
+
+type preemptionVariant int
+
+const (
+	// Cannot be preempted
+	Never preemptionVariant = iota
+	// Candidate within the same CQ as the preemptor
+	WithinCQ
+	// Preemptor has preferential access to the resources needing preemption
+	// over the candidate, because of its CQ position in the cohort topology.
+	HiearchicalReclaim
+	// Can only be preempted if preemptor CQ (after all preemptions and the
+	// admission of the incoming workload) would not be borrowing any quota
+	ReclaimWithoutBorrowing
+	// Can be preemped even if preemptor CQ would be borrowing
+	ReclaimWhileBorrowing
+)
+
+func (m preemptionVariant) PreemptionReason() string {
+	switch m {
+	case WithinCQ:
+		return kueue.InClusterQueueReason
+	case HiearchicalReclaim:
+		return kueue.InCohortReclamationReason
+	case ReclaimWhileBorrowing:
+		return kueue.InCohortReclaimWhileBorrowingReason
+	case ReclaimWithoutBorrowing:
+		return kueue.InCohortReclamationReason
+	}
+	return "Unknown"
+}
+
+type HierarchicalPreemptionCtx struct {
+	Wl                *kueue.Workload
+	Cq                *cache.ClusterQueueSnapshot
+	FrsNeedPreemption sets.Set[resources.FlavorResource]
+	Requests          resources.FlavorResourceQuantities
+	WorkloadOrdering  workload.Ordering
+}
+
+func IsBorrowingWithinCohortForbidden(cq *cache.ClusterQueueSnapshot) (bool, *int32) {
+	borrowWithinCohort := cq.Preemption.BorrowWithinCohort
+	if borrowWithinCohort == nil || borrowWithinCohort.Policy == kueue.BorrowWithinCohortPolicyNever {
+		return true, nil
+	}
+	return false, borrowWithinCohort.MaxPriorityThreshold
+}
+
+// classifyPreemptionVariant evaluates, based on config and priorities, the
+// preemption type for a given candidate
+func classifyPreemptionVariant(ctx *HierarchicalPreemptionCtx, wl *workload.Info, haveHierarchicalAdvantage bool) preemptionVariant {
+	if !WorkloadUsesResources(wl, ctx.FrsNeedPreemption) {
+		return Never
+	}
+	incomingPriority := priority.Priority(ctx.Wl)
+	candidatePriority := priority.Priority(wl.Obj)
+	if !satisfiesPreemptionPolicy(ctx, wl, incomingPriority, candidatePriority) {
+		return Never
+	}
+	if wl.ClusterQueue == ctx.Cq.Name {
+		return WithinCQ
+	}
+	if haveHierarchicalAdvantage {
+		return HiearchicalReclaim
+	}
+	borrowWithinCohortForbidden, borrowWithinCohortThreshold := IsBorrowingWithinCohortForbidden(ctx.Cq)
+	if borrowWithinCohortForbidden {
+		return ReclaimWithoutBorrowing
+	}
+	if isAboveBorrowingThreshold(candidatePriority, incomingPriority, borrowWithinCohortThreshold) {
+		return ReclaimWithoutBorrowing
+	}
+	return ReclaimWhileBorrowing
+}
+
+func satisfiesPreemptionPolicy(ctx *HierarchicalPreemptionCtx, wl *workload.Info, incomingPriority, candidatePriority int32) bool {
+	var preemptionPolicy kueue.PreemptionPolicy
+	if wl.ClusterQueue == ctx.Cq.Name {
+		preemptionPolicy = ctx.Cq.Preemption.WithinClusterQueue
+	} else {
+		preemptionPolicy = ctx.Cq.Preemption.ReclaimWithinCohort
+	}
+	lowerPriority := incomingPriority > candidatePriority
+	if preemptionPolicy == kueue.PreemptionPolicyLowerPriority {
+		return lowerPriority
+	}
+	if preemptionPolicy == kueue.PreemptionPolicyLowerOrNewerEqualPriority {
+		preemptorTS := ctx.WorkloadOrdering.GetQueueOrderTimestamp(ctx.Wl)
+		newerEqualPriority := (incomingPriority == candidatePriority) && preemptorTS.Before(ctx.WorkloadOrdering.GetQueueOrderTimestamp(wl.Obj))
+		return (lowerPriority || newerEqualPriority)
+	}
+	return preemptionPolicy == kueue.PreemptionPolicyAny
+}
+
+func isAboveBorrowingThreshold(candidatePriority, incomingPriority int32, borrowWithinCohortThreshold *int32) bool {
+	if candidatePriority >= incomingPriority {
+		return true
+	}
+	if borrowWithinCohortThreshold == nil {
+		return false
+	}
+	return candidatePriority > *borrowWithinCohortThreshold
+}
+
+func collectSameQueueCandidates(ctx *HierarchicalPreemptionCtx) []*candidateElem {
+	if ctx.Cq.Preemption.WithinClusterQueue == kueue.PreemptionPolicyNever {
+		return []*candidateElem{}
+	}
+	return getCandidatesFromCQ(ctx.Cq, nil, ctx, false)
+}
+
+func getCandidatesFromCQ(cq *cache.ClusterQueueSnapshot, lca *cache.CohortSnapshot, ctx *HierarchicalPreemptionCtx, hasHiearchicalAdvantage bool) []*candidateElem {
+	candidates := []*candidateElem{}
+	for _, candidateWl := range cq.Workloads {
+		preemptionVariant := classifyPreemptionVariant(ctx, candidateWl, hasHiearchicalAdvantage)
+		if preemptionVariant == Never {
+			continue
+		}
+		candidates = append(candidates,
+			&candidateElem{
+				wl:                candidateWl,
+				lca:               lca,
+				preemptionVariant: preemptionVariant,
+			})
+	}
+	return candidates
+}
+
+func collectCandidatesForHierarchicalReclaim(ctx *HierarchicalPreemptionCtx) ([]*candidateElem, []*candidateElem) {
+	hierarchyCandidates := []*candidateElem{}
+	priorityCandidates := []*candidateElem{}
+	if !ctx.Cq.HasParent() || ctx.Cq.Preemption.ReclaimWithinCohort == kueue.PreemptionPolicyNever {
+		return hierarchyCandidates, priorityCandidates
+	}
+	var previousSubtreeRoot *cache.CohortSnapshot
+	var candidateList *[]*candidateElem
+	var fits bool
+	hasHierarchicalAdvantage, remainingRequests := cache.QuantitiesFitInQuota(ctx.Cq, ctx.Requests)
+	for currentSubtreeRoot := range ctx.Cq.PathParentToRoot() {
+		if hasHierarchicalAdvantage {
+			candidateList = &hierarchyCandidates
+		} else {
+			candidateList = &priorityCandidates
+		}
+		collectCandidatesInSubtree(ctx, currentSubtreeRoot, currentSubtreeRoot, previousSubtreeRoot, hasHierarchicalAdvantage, candidateList)
+		fits, remainingRequests = cache.QuantitiesFitInQuota(currentSubtreeRoot, remainingRequests)
+		// Once we find a subtree sT that fits the requests, we will look for workloads that use quota
+		// of that subtree. The preemptor will have hierarchical advantage over all such workloads
+		// because it belongs to subtree sT. For that reason variable hasHierarchicalAdvantage
+		// remains true in subsequent iterations of the loop.
+		hasHierarchicalAdvantage = hasHierarchicalAdvantage || fits
+		previousSubtreeRoot = currentSubtreeRoot
+	}
+	return hierarchyCandidates, priorityCandidates
+}
+
+// visit the nodes in the hierarchy and collect the ones that exceed quota
+// avoid subtrees that are within quota and the skipped subtree
+func collectCandidatesInSubtree(ctx *HierarchicalPreemptionCtx, currentCohort *cache.CohortSnapshot, subtreeRoot *cache.CohortSnapshot, skipSubtree *cache.CohortSnapshot, hasHierarchicalAdvantage bool, result *[]*candidateElem) {
+	for _, childCohort := range currentCohort.ChildCohorts() {
+		// we already processed this subtree
+		if childCohort == skipSubtree {
+			continue
+		}
+		// don't look for candidates in subtrees that are not exceeding their quotas
+		if cache.IsWithinNominalInResources(childCohort, ctx.FrsNeedPreemption) {
+			continue
+		}
+		collectCandidatesInSubtree(ctx, childCohort, subtreeRoot, skipSubtree, hasHierarchicalAdvantage, result)
+	}
+	for _, childCq := range currentCohort.ChildCQs() {
+		if childCq == ctx.Cq {
+			continue
+		}
+		if !cache.IsWithinNominalInResources(childCq, ctx.FrsNeedPreemption) {
+			*result = append(*result, getCandidatesFromCQ(childCq, subtreeRoot, ctx, hasHierarchicalAdvantage)...)
+		}
+	}
+}
+
+// getNodeHeight calculates the distance to the furthest leaf
+func getNodeHeight(node *cache.CohortSnapshot) int {
+	maxHeight := min(node.ChildCount(), 1)
+	for _, childCohort := range node.ChildCohorts() {
+		maxHeight = max(maxHeight, getNodeHeight(childCohort)+1)
+	}
+	return maxHeight
+}
+
+// FindHeightOfLowestSubtreeThatFits returns height of a lowest subtree in the cohort
+// that fits additional val of resource fr. If no such subtree exists, it returns
+// height the whole cohort hierarchy. Note that height of a trivial subtree
+// with only one node is 0. It also returns if the returned subtree is smaller than the whole cohort tree.
+func FindHeightOfLowestSubtreeThatFits(c *cache.ClusterQueueSnapshot, fr resources.FlavorResource, val int64) (int, bool) {
+	if !(c.BorrowingWith(fr, val) && c.HasParent()) {
+		return 0, c.HasParent()
+	}
+	remaining := val - cache.LocalAvailable(c, fr)
+	for trackingNode := range c.PathParentToRoot() {
+		if !trackingNode.BorrowingWith(fr, remaining) {
+			return getNodeHeight(trackingNode), trackingNode.HasParent()
+		}
+		remaining -= cache.LocalAvailable(trackingNode, fr)
+	}
+	// no fit found
+	return getNodeHeight(c.Parent().Root()), false
+}
diff --git a/pkg/scheduler/preemption/fairsharing/least_common_ancestor.go b/pkg/scheduler/preemption/fairsharing/least_common_ancestor.go
index fb4857e6b..cdbaf974b 100644
--- a/pkg/scheduler/preemption/fairsharing/least_common_ancestor.go
+++ b/pkg/scheduler/preemption/fairsharing/least_common_ancestor.go
@@ -38,7 +38,8 @@ func getLCA(t *TargetClusterQueue) *cache.CohortSnapshot {
 			return ancestor
 		}
 	}
-	return nil
+	// to make the compiler happy
+	panic("serious bug: could not find LeastCommonAncestor")
 }
 
 // getAlmostLCA traverses from a ClusterQueue towards the root,
@@ -52,5 +53,6 @@ func getAlmostLCA(cq *cache.ClusterQueueSnapshot, lca *cache.CohortSnapshot) alm
 		}
 		aLca = ancestor
 	}
-	panic("Could not find least common ancestor.")
+	// to make the compiler happy
+	panic("serious bug: could not find AlmostLeastCommonAncestor")
 }
diff --git a/pkg/scheduler/preemption/fairsharing/target.go b/pkg/scheduler/preemption/fairsharing/target.go
index ec29b882e..11e6fda95 100644
--- a/pkg/scheduler/preemption/fairsharing/target.go
+++ b/pkg/scheduler/preemption/fairsharing/target.go
@@ -65,10 +65,9 @@ func (t *TargetClusterQueue) ComputeShares() (PreemptorNewShare, TargetOldShare)
 // will depend on LendingLimits of the children. See
 // cache.resource_node.go.
 func (t *TargetClusterQueue) ComputeTargetShareAfterRemoval(wl *workload.Info) TargetNewShare {
+	revertSimulation := t.targetCq.SimulateUsageRemoval(wl.Usage())
+	defer revertSimulation()
+
 	_, almostLCA := getAlmostLCAs(t)
-	usage := wl.Usage()
-	revertSimulation := t.targetCq.SimulateUsageRemoval(usage)
-	drs := almostLCA.DominantResourceShare()
-	revertSimulation()
-	return TargetNewShare(drs)
+	return TargetNewShare(almostLCA.DominantResourceShare())
 }
diff --git a/pkg/scheduler/preemption/preemption.go b/pkg/scheduler/preemption/preemption.go
index 44f2593a3..a089a0e65 100644
--- a/pkg/scheduler/preemption/preemption.go
+++ b/pkg/scheduler/preemption/preemption.go
@@ -42,6 +42,7 @@ import (
 	"sigs.k8s.io/kueue/pkg/metrics"
 	"sigs.k8s.io/kueue/pkg/resources"
 	"sigs.k8s.io/kueue/pkg/scheduler/flavorassigner"
+	"sigs.k8s.io/kueue/pkg/scheduler/preemption/classical"
 	"sigs.k8s.io/kueue/pkg/scheduler/preemption/fairsharing"
 	"sigs.k8s.io/kueue/pkg/util/priority"
 	"sigs.k8s.io/kueue/pkg/util/routine"
@@ -97,26 +98,6 @@ func (p *Preemptor) OverrideApply(f func(context.Context, *kueue.Workload, strin
 	p.applyPreemption = f
 }
 
-func candidatesOnlyFromQueue(candidates []*workload.Info, clusterQueue kueue.ClusterQueueReference) []*workload.Info {
-	result := make([]*workload.Info, 0, len(candidates))
-	for _, wi := range candidates {
-		if wi.ClusterQueue == clusterQueue {
-			result = append(result, wi)
-		}
-	}
-	return result
-}
-
-func candidatesFromCQOrUnderThreshold(candidates []*workload.Info, clusterQueue kueue.ClusterQueueReference, threshold int32) []*workload.Info {
-	result := make([]*workload.Info, 0, len(candidates))
-	for _, wi := range candidates {
-		if wi.ClusterQueue == clusterQueue || priority.Priority(wi.Obj) < threshold {
-			result = append(result, wi)
-		}
-	}
-	return result
-}
-
 type Target struct {
 	WorkloadInfo *workload.Info
 	Reason       string
@@ -142,65 +123,10 @@ func (p *Preemptor) GetTargets(log logr.Logger, wl workload.Info, assignment fla
 }
 
 func (p *Preemptor) getTargets(preemptionCtx *preemptionCtx) []*Target {
-	candidates := p.findCandidates(preemptionCtx.preemptor.Obj, preemptionCtx.preemptorCQ, preemptionCtx.frsNeedPreemption)
-	if len(candidates) == 0 {
-		return nil
-	}
-	sort.Slice(candidates, candidatesOrdering(candidates, preemptionCtx.preemptorCQ.Name, p.clock.Now()))
 	if p.enableFairSharing {
-		return fairPreemptions(preemptionCtx, candidates, p.fsStrategies)
-	}
-
-	sameQueueCandidates := candidatesOnlyFromQueue(candidates, preemptionCtx.preemptorCQ.Name)
-
-	// To avoid flapping, Kueue only allows preemption of workloads from the same
-	// queue if borrowing. Preemption of workloads from queues can happen only
-	// if not borrowing at the same time. Kueue prioritizes preemption of
-	// workloads from the other queues (that borrowed resources) first, before
-	// trying to preempt more own workloads and borrow at the same time.
-	if len(sameQueueCandidates) == len(candidates) {
-		// There is no possible preemption of workloads from other queues,
-		// so we'll try borrowing.
-		return minimalPreemptions(preemptionCtx, candidates, true, nil)
-	}
-
-	// There is a potential of preemption of workloads from the other queue in the
-	// cohort. We proceed with borrowing only if the dedicated policy
-	// (borrowWithinCohort) is enabled. This ensures the preempted workloads
-	// have lower priority, and so they will not preempt the preemptor when
-	// requeued.
-	if borrowWithinCohort, thresholdPrio := canBorrowWithinCohort(preemptionCtx); borrowWithinCohort {
-		if !queueUnderNominalInResourcesNeedingPreemption(preemptionCtx) {
-			// It can only preempt workloads from another CQ if they are strictly under allowBorrowingBelowPriority.
-			candidates = candidatesFromCQOrUnderThreshold(candidates, preemptionCtx.preemptor.ClusterQueue, *thresholdPrio)
-		}
-		return minimalPreemptions(preemptionCtx, candidates, true, thresholdPrio)
-	}
-
-	// Only try preemptions in the cohort, without borrowing, if the target clusterqueue is still
-	// under nominal quota for all resources.
-	if queueUnderNominalInResourcesNeedingPreemption(preemptionCtx) {
-		if targets := minimalPreemptions(preemptionCtx, candidates, false, nil); len(targets) > 0 {
-			return targets
-		}
+		return p.fairPreemptions(preemptionCtx, p.fsStrategies)
 	}
-
-	// Final attempt. This time only candidates from the same queue, but
-	// with borrowing.
-	return minimalPreemptions(preemptionCtx, sameQueueCandidates, true, nil)
-}
-
-// canBorrowWithinCohort returns whether the behavior is enabled for the ClusterQueue and the threshold priority to use.
-func canBorrowWithinCohort(preemptionCtx *preemptionCtx) (bool, *int32) {
-	borrowWithinCohort := preemptionCtx.preemptorCQ.Preemption.BorrowWithinCohort
-	if borrowWithinCohort == nil || borrowWithinCohort.Policy == kueue.BorrowWithinCohortPolicyNever {
-		return false, nil
-	}
-	threshold := priority.Priority(preemptionCtx.preemptor.Obj)
-	if borrowWithinCohort.MaxPriorityThreshold != nil && *borrowWithinCohort.MaxPriorityThreshold < threshold {
-		threshold = *borrowWithinCohort.MaxPriorityThreshold + 1
-	}
-	return true, &threshold
+	return p.classicalPreemptions(preemptionCtx)
 }
 
 var HumanReadablePreemptionReasons = map[string]string{
@@ -264,66 +190,71 @@ func (p *Preemptor) applyPreemptionWithSSA(ctx context.Context, w *kueue.Workloa
 	return workload.ApplyAdmissionStatus(ctx, p.client, w, true, p.clock)
 }
 
-// minimalPreemptions implements a heuristic to find a minimal set of Workloads
+type preemptionAttemptOpts struct {
+	borrowing bool
+}
+
+// classicalPreemptions implements a heuristic to find a minimal set of Workloads
 // to preempt.
 // The heuristic first removes candidates, in the input order, while their
 // ClusterQueues are still borrowing resources and while the incoming Workload
 // doesn't fit in the quota.
 // Once the Workload fits, the heuristic tries to add Workloads back, in the
 // reverse order in which they were removed, while the incoming Workload still
-// fits.
-func minimalPreemptions(preemptionCtx *preemptionCtx, candidates []*workload.Info, allowBorrowing bool, allowBorrowingBelowPriority *int32) []*Target {
-	if logV := preemptionCtx.log.V(5); logV.Enabled() {
-		logV.Info("Simulating preemption", "candidates", workload.References(candidates), "resourcesRequiringPreemption", preemptionCtx.frsNeedPreemption.UnsortedList(), "allowBorrowing", allowBorrowing, "allowBorrowingBelowPriority", allowBorrowingBelowPriority, "preemptingWorkload", klog.KObj(preemptionCtx.preemptor.Obj))
-	}
-	// Simulate removing all candidates from the ClusterQueue and cohort.
-	var targets []*Target
-	fits := false
-	for _, candWl := range candidates {
-		candCQ := preemptionCtx.snapshot.ClusterQueue(candWl.ClusterQueue)
-		reason := kueue.InClusterQueueReason
-		if preemptionCtx.preemptorCQ != candCQ {
-			if !cqIsBorrowing(candCQ, preemptionCtx.frsNeedPreemption) {
-				continue
-			}
-			reason = kueue.InCohortReclamationReason
-			if allowBorrowingBelowPriority != nil {
-				if priority.Priority(candWl.Obj) >= *allowBorrowingBelowPriority {
-					// We set allowBorrowing=false if there is a candidate with priority
-					// exceeding allowBorrowingBelowPriority added to targets.
-					//
-					// We need to be careful mutating allowBorrowing. We rely on the
-					// fact that once there is a candidate exceeding the priority added
-					// to targets, then at least one such candidate is present in the
-					// final set of targets (after the second phase of the function).
-					//
-					// This is true, because the candidates are ordered according
-					// to priorities (from lowest to highest, using candidatesOrdering),
-					// and the last added target is not removed in the second phase of
-					// the function.
-					allowBorrowing = false
-				} else {
-					reason = kueue.InCohortReclaimWhileBorrowingReason
-				}
+// fits
+func (p *Preemptor) classicalPreemptions(preemptionCtx *preemptionCtx) []*Target {
+	hierarchicalReclaimCtx := &classical.HierarchicalPreemptionCtx{
+		Wl:                preemptionCtx.preemptor.Obj,
+		Cq:                preemptionCtx.preemptorCQ,
+		FrsNeedPreemption: preemptionCtx.frsNeedPreemption,
+		Requests:          preemptionCtx.workloadUsage.Quota,
+		WorkloadOrdering:  p.workloadOrdering,
+	}
+	candidatesGenerator := classical.NewCandidateIterator(hierarchicalReclaimCtx, preemptionCtx.frsNeedPreemption, preemptionCtx.snapshot, p.clock, CandidatesOrdering)
+	var attemptPossibleOpts []preemptionAttemptOpts
+	borrowWithinCohortForbidden, _ := classical.IsBorrowingWithinCohortForbidden(preemptionCtx.preemptorCQ)
+	// We have three types of candidates:
+	// 1. Hierarchy candidates. Candidates over which the incoming workload has a
+	// 	  hierarchical advantage (it is closer to the quota used by the candidate).
+	//    We can preempt such candidates regardless of their priority.
+	// 2. Priority candidates. Candidates over which there is no hiearchical advantage
+	//    but the possibility to preempt is determined based on priorities.
+	// 	  We respect the BorrowWithinCohort configuration only for these candidates.
+	// 3. Same queue candidates.
+	// We can only preempt a priority candidate with priority > MaxPriorityThreshold
+	// if the target CQ is not borrowing (by the definition of the MaxPriorityThreshold).
+	// We sometimes need to consider both options allowBorrowing = true and false
+	// (because with false we have more candidates but cannot use borrowing).
+	// The order in which the options are considered is arbitrary and the condition
+	// in which we try allowBorrowing=false before true is to keep compatibility with
+	// previous versions.
+	switch {
+	case candidatesGenerator.NoCandidateFromOtherQueues || (borrowWithinCohortForbidden && !queueUnderNominalInResourcesNeedingPreemption(preemptionCtx)):
+		attemptPossibleOpts = []preemptionAttemptOpts{{true}}
+	case borrowWithinCohortForbidden && candidatesGenerator.NoCandidateForHierarchicalReclaim:
+		attemptPossibleOpts = []preemptionAttemptOpts{{false}, {true}}
+	default:
+		attemptPossibleOpts = []preemptionAttemptOpts{{true}, {false}}
+	}
+
+	for _, attemptOpts := range attemptPossibleOpts {
+		var targets []*Target
+		candidatesGenerator.Reset()
+		for candidate, reason := candidatesGenerator.Next(attemptOpts.borrowing); candidate != nil; candidate, reason = candidatesGenerator.Next(attemptOpts.borrowing) {
+			preemptionCtx.snapshot.RemoveWorkload(candidate)
+			targets = append(targets, &Target{
+				WorkloadInfo: candidate,
+				Reason:       reason,
+			})
+			if workloadFits(preemptionCtx, attemptOpts.borrowing) {
+				targets = fillBackWorkloads(preemptionCtx, targets, attemptOpts.borrowing)
+				restoreSnapshot(preemptionCtx.snapshot, targets)
+				return targets
 			}
 		}
-		preemptionCtx.snapshot.RemoveWorkload(candWl)
-		targets = append(targets, &Target{
-			WorkloadInfo: candWl,
-			Reason:       reason,
-		})
-		if workloadFits(preemptionCtx, allowBorrowing) {
-			fits = true
-			break
-		}
-	}
-	if !fits {
 		restoreSnapshot(preemptionCtx.snapshot, targets)
-		return nil
 	}
-	targets = fillBackWorkloads(preemptionCtx, targets, allowBorrowing)
-	restoreSnapshot(preemptionCtx.snapshot, targets)
-	return targets
+	return nil
 }
 
 func fillBackWorkloads(preemptionCtx *preemptionCtx, targets []*Target, allowBorrowing bool) []*Target {
@@ -439,7 +370,12 @@ func runSecondFsStrategy(retryCandidates []*workload.Info, preemptionCtx *preemp
 	return false, targets
 }
 
-func fairPreemptions(preemptionCtx *preemptionCtx, candidates []*workload.Info, strategies []fairsharing.Strategy) []*Target {
+func (p *Preemptor) fairPreemptions(preemptionCtx *preemptionCtx, strategies []fairsharing.Strategy) []*Target {
+	candidates := p.findCandidates(preemptionCtx.preemptor.Obj, preemptionCtx.preemptorCQ, preemptionCtx.frsNeedPreemption)
+	if len(candidates) == 0 {
+		return nil
+	}
+	sort.Slice(candidates, CandidatesOrdering(candidates, preemptionCtx.preemptorCQ.Name, p.clock.Now()))
 	if logV := preemptionCtx.log.V(5); logV.Enabled() {
 		logV.Info("Simulating fair preemption", "candidates", workload.References(candidates), "resourcesRequiringPreemption", preemptionCtx.frsNeedPreemption.UnsortedList(), "preemptingWorkload", klog.KObj(preemptionCtx.preemptor.Obj))
 	}
@@ -482,7 +418,7 @@ func (p *Preemptor) findCandidates(wl *kueue.Workload, cq *cache.ClusterQueueSna
 	wlPriority := priority.Priority(wl)
 
 	if cq.Preemption.WithinClusterQueue != kueue.PreemptionPolicyNever {
-		considerSamePrio := (cq.Preemption.WithinClusterQueue == kueue.PreemptionPolicyLowerOrNewerEqualPriority)
+		considerSamePrio := cq.Preemption.WithinClusterQueue == kueue.PreemptionPolicyLowerOrNewerEqualPriority
 		preemptorTS := p.workloadOrdering.GetQueueOrderTimestamp(wl)
 
 		for _, candidateWl := range cq.Workloads {
@@ -495,7 +431,7 @@ func (p *Preemptor) findCandidates(wl *kueue.Workload, cq *cache.ClusterQueueSna
 				continue
 			}
 
-			if !workloadUsesResources(candidateWl, frsNeedPreemption) {
+			if !classical.WorkloadUsesResources(candidateWl, frsNeedPreemption) {
 				continue
 			}
 			candidates = append(candidates, candidateWl)
@@ -513,7 +449,7 @@ func (p *Preemptor) findCandidates(wl *kueue.Workload, cq *cache.ClusterQueueSna
 				if onlyLowerPriority && priority.Priority(candidateWl.Obj) >= priority.Priority(wl) {
 					continue
 				}
-				if !workloadUsesResources(candidateWl, frsNeedPreemption) {
+				if !classical.WorkloadUsesResources(candidateWl, frsNeedPreemption) {
 					continue
 				}
 				candidates = append(candidates, candidateWl)
@@ -535,17 +471,6 @@ func cqIsBorrowing(cq *cache.ClusterQueueSnapshot, frsNeedPreemption sets.Set[re
 	return false
 }
 
-func workloadUsesResources(wl *workload.Info, frsNeedPreemption sets.Set[resources.FlavorResource]) bool {
-	for _, ps := range wl.TotalRequests {
-		for res, flv := range ps.Flavors {
-			if frsNeedPreemption.Has(resources.FlavorResource{Flavor: flv, Resource: res}) {
-				return true
-			}
-		}
-	}
-	return false
-}
-
 // workloadFits determines if the workload requests would fit given the
 // requestable resources and simulated usage of the ClusterQueue and its cohort,
 // if it belongs to one.
@@ -588,7 +513,7 @@ func queueUnderNominalInResourcesNeedingPreemption(preemptionCtx *preemptionCtx)
 // same ClusterQueue as the preemptor.
 // 2. Workloads with lower priority first.
 // 3. Workloads admitted more recently first.
-func candidatesOrdering(candidates []*workload.Info, cq kueue.ClusterQueueReference, now time.Time) func(int, int) bool {
+func CandidatesOrdering(candidates []*workload.Info, cq kueue.ClusterQueueReference, now time.Time) func(int, int) bool {
 	return func(i, j int) bool {
 		a := candidates[i]
 		b := candidates[j]
diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go
index 8e24abe4e..05fda284a 100644
--- a/pkg/scheduler/scheduler.go
+++ b/pkg/scheduler/scheduler.go
@@ -402,7 +402,7 @@ func quotaResourcesToReserve(e *entry, cq *cache.ClusterQueueSnapshot) resources
 	reservedUsage := make(resources.FlavorResourceQuantities)
 	for fr, usage := range e.assignment.Usage.Quota {
 		cqQuota := cq.QuotaFor(fr)
-		if e.assignment.Borrowing {
+		if e.assignment.Borrowing > 0 {
 			if cqQuota.BorrowingLimit == nil {
 				reservedUsage[fr] = usage
 			} else {
@@ -580,7 +580,7 @@ func (e entryOrdering) Less(i, j int) bool {
 	aBorrows := a.assignment.Borrows()
 	bBorrows := b.assignment.Borrows()
 	if aBorrows != bBorrows {
-		return !aBorrows
+		return aBorrows < bBorrows
 	}
 
 	// 2. Higher priority first if not disabled.
@@ -651,8 +651,7 @@ func (s *Scheduler) requeueAndUpdate(ctx context.Context, e entry) {
 	log.V(2).Info("Workload re-queued", "workload", klog.KObj(e.Obj), "clusterQueue", klog.KRef("", string(e.ClusterQueue)), "queue", klog.KRef(e.Obj.Namespace, e.Obj.Spec.QueueName), "requeueReason", e.requeueReason, "added", added, "status", e.status)
 
 	if e.status == notNominated || e.status == skipped {
-		patch := workload.BaseSSAWorkload(e.Obj)
-		workload.AdmissionStatusPatch(e.Obj, patch, true)
+		patch := workload.PrepareWorkloadPatch(e.Obj, true, s.clock)
 		reservationIsChanged := workload.UnsetQuotaReservationWithCondition(patch, "Pending", e.inadmissibleMsg, s.clock.Now())
 		resourceRequestsIsChanged := workload.PropagateResourceRequests(patch, &e.Info)
 		if reservationIsChanged || resourceRequestsIsChanged {
diff --git a/pkg/util/admissioncheck/admissioncheck.go b/pkg/util/admissioncheck/admissioncheck.go
index ba0bb6312..b7db98faa 100644
--- a/pkg/util/admissioncheck/admissioncheck.go
+++ b/pkg/util/admissioncheck/admissioncheck.go
@@ -89,9 +89,9 @@ func (ch *ConfigHelper[PtrT, T]) ConfigFromRef(ctx context.Context, ref *kueue.A
 
 // ConfigForAdmissionCheck - get the configuration of the admission check identified by its name if it uses the
 // helpers configuration type.
-func (ch *ConfigHelper[PtrT, T]) ConfigForAdmissionCheck(ctx context.Context, checkName string) (PtrT, error) {
+func (ch *ConfigHelper[PtrT, T]) ConfigForAdmissionCheck(ctx context.Context, checkName kueue.AdmissionCheckReference) (PtrT, error) {
 	ac := &kueue.AdmissionCheck{}
-	if err := ch.client.Get(ctx, types.NamespacedName{Name: checkName}, ac); err != nil {
+	if err := ch.client.Get(ctx, types.NamespacedName{Name: string(checkName)}, ac); err != nil {
 		return nil, err
 	}
 
@@ -131,15 +131,15 @@ func IndexerByConfigFunction(controllerName string, gvk schema.GroupVersionKind)
 }
 
 // FilterForController - returns a list of check names controlled by ControllerName.
-func FilterForController(ctx context.Context, c client.Client, states []kueue.AdmissionCheckState, controllerName string) ([]string, error) {
-	var retActive []string
+func FilterForController(ctx context.Context, c client.Client, states []kueue.AdmissionCheckState, controllerName string) ([]kueue.AdmissionCheckReference, error) {
+	var retActive []kueue.AdmissionCheckReference
 	for _, state := range states {
 		ac := &kueue.AdmissionCheck{}
 
-		if err := c.Get(ctx, types.NamespacedName{Name: state.Name}, ac); client.IgnoreNotFound(err) != nil {
+		if err := c.Get(ctx, types.NamespacedName{Name: string(state.Name)}, ac); client.IgnoreNotFound(err) != nil {
 			return nil, err
 		} else if err == nil && ac.Spec.ControllerName == controllerName {
-			retActive = append(retActive, ac.Name)
+			retActive = append(retActive, kueue.AdmissionCheckReference(ac.Name))
 		}
 	}
 	return retActive, nil
@@ -157,15 +157,15 @@ func FilterProvReqAnnotations(annotations map[string]string) map[string]string {
 }
 
 // NewAdmissionChecks aggregates AdmissionChecks from .spec.AdmissionChecks and .spec.AdmissionChecksStrategy
-func NewAdmissionChecks(cq *kueue.ClusterQueue) map[string]sets.Set[kueue.ResourceFlavorReference] {
-	var checks map[string]sets.Set[kueue.ResourceFlavorReference]
+func NewAdmissionChecks(cq *kueue.ClusterQueue) map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference] {
+	var checks map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference]
 	if cq.Spec.AdmissionChecksStrategy != nil {
-		checks = make(map[string]sets.Set[kueue.ResourceFlavorReference], len(cq.Spec.AdmissionChecksStrategy.AdmissionChecks))
+		checks = make(map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference], len(cq.Spec.AdmissionChecksStrategy.AdmissionChecks))
 		for _, check := range cq.Spec.AdmissionChecksStrategy.AdmissionChecks {
 			checks[check.Name] = sets.New(check.OnFlavors...)
 		}
 	} else {
-		checks = make(map[string]sets.Set[kueue.ResourceFlavorReference], len(cq.Spec.AdmissionChecks))
+		checks = make(map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference], len(cq.Spec.AdmissionChecks))
 		for _, checkName := range cq.Spec.AdmissionChecks {
 			checks[checkName] = sets.New[kueue.ResourceFlavorReference]()
 		}
diff --git a/pkg/util/maps/maps.go b/pkg/util/maps/maps.go
index f5224b119..576f20c1e 100644
--- a/pkg/util/maps/maps.go
+++ b/pkg/util/maps/maps.go
@@ -81,13 +81,13 @@ func FilterKeys[K comparable, V any, M ~map[K]V](m M, k []K) M {
 	return ret
 }
 
-// DeepCopySets create a deep copy of map[string]Set which would otherwise be referenced
-func DeepCopySets[T comparable](src map[string]sets.Set[T]) map[string]sets.Set[T] {
-	copy := make(map[string]sets.Set[T], len(src))
+// DeepCopySets creates a deep copy of map[K]Set which would otherwise be referenced
+func DeepCopySets[K comparable, T comparable](src map[K]sets.Set[T]) map[K]sets.Set[T] {
+	c := make(map[K]sets.Set[T], len(src))
 	for key, set := range src {
-		copy[key] = set.Clone()
+		c[key] = set.Clone()
 	}
-	return copy
+	return c
 }
 
 // SyncMap - generic RWMutex protected map.
diff --git a/pkg/util/strings/strings.go b/pkg/util/strings/strings.go
index c3bd2868d..09f65acb2 100644
--- a/pkg/util/strings/strings.go
+++ b/pkg/util/strings/strings.go
@@ -27,3 +27,12 @@ func StringContainsSubstrings(s string, substrings ...string) bool {
 
 	return true
 }
+
+// Join function for string-like types.
+func Join[T ~string](a []T, sep string) string {
+	strs := make([]string, len(a))
+	for i, v := range a {
+		strs[i] = string(v)
+	}
+	return strings.Join(strs, sep)
+}
diff --git a/pkg/webhooks/workload_webhook.go b/pkg/webhooks/workload_webhook.go
index 4d9295c4f..0d838c985 100644
--- a/pkg/webhooks/workload_webhook.go
+++ b/pkg/webhooks/workload_webhook.go
@@ -184,7 +184,7 @@ func validatePodSetUpdates(acs *kueue.AdmissionCheckState, obj *kueue.Workload,
 
 func validateImmutablePodSetUpdates(newObj, oldObj *kueue.Workload, basePath *field.Path) field.ErrorList {
 	var allErrs field.ErrorList
-	newAcs := slices.ToRefMap(newObj.Status.AdmissionChecks, func(f *kueue.AdmissionCheckState) string { return f.Name })
+	newAcs := slices.ToRefMap(newObj.Status.AdmissionChecks, func(f *kueue.AdmissionCheckState) kueue.AdmissionCheckReference { return f.Name })
 	for i := range oldObj.Status.AdmissionChecks {
 		oldAc := &oldObj.Status.AdmissionChecks[i]
 		newAc, found := newAcs[oldAc.Name]
diff --git a/pkg/workload/admissionchecks.go b/pkg/workload/admissionchecks.go
index 9907edd41..33166a012 100644
--- a/pkg/workload/admissionchecks.go
+++ b/pkg/workload/admissionchecks.go
@@ -77,7 +77,7 @@ func SyncAdmittedCondition(w *kueue.Workload, now time.Time) bool {
 }
 
 // FindAdmissionCheck - returns a pointer to the check identified by checkName if found in checks.
-func FindAdmissionCheck(checks []kueue.AdmissionCheckState, checkName string) *kueue.AdmissionCheckState {
+func FindAdmissionCheck(checks []kueue.AdmissionCheckState, checkName kueue.AdmissionCheckReference) *kueue.AdmissionCheckState {
 	for i := range checks {
 		if checks[i].Name == checkName {
 			return &checks[i]
@@ -155,7 +155,7 @@ func HasAllChecksReady(wl *kueue.Workload) bool {
 }
 
 // HasAllChecks returns true if all the mustHaveChecks are present in the workload.
-func HasAllChecks(wl *kueue.Workload, mustHaveChecks sets.Set[string]) bool {
+func HasAllChecks(wl *kueue.Workload, mustHaveChecks sets.Set[kueue.AdmissionCheckReference]) bool {
 	if mustHaveChecks.Len() == 0 {
 		return true
 	}
diff --git a/pkg/workload/workload.go b/pkg/workload/workload.go
index 1cd061e9c..f66e871d6 100644
--- a/pkg/workload/workload.go
+++ b/pkg/workload/workload.go
@@ -709,10 +709,15 @@ func AdmissionChecksStatusPatch(w *kueue.Workload, wlCopy *kueue.Workload, c clo
 // If strict is true, resourceVersion will be part of the patch, make this call fail if Workload
 // was changed.
 func ApplyAdmissionStatus(ctx context.Context, c client.Client, w *kueue.Workload, strict bool, clk clock.Clock) error {
+	wlCopy := PrepareWorkloadPatch(w, strict, clk)
+	return ApplyAdmissionStatusPatch(ctx, c, wlCopy)
+}
+
+func PrepareWorkloadPatch(w *kueue.Workload, strict bool, clk clock.Clock) *kueue.Workload {
 	wlCopy := BaseSSAWorkload(w)
 	AdmissionStatusPatch(w, wlCopy, strict)
 	AdmissionChecksStatusPatch(w, wlCopy, clk)
-	return ApplyAdmissionStatusPatch(ctx, c, wlCopy)
+	return wlCopy
 }
 
 // ApplyAdmissionStatusPatch applies the patch of admission related status fields of a workload with SSA.
@@ -788,8 +793,7 @@ func IsActive(w *kueue.Workload) bool {
 // IsEvictedByDeactivation returns true if the workload is evicted by deactivation.
 func IsEvictedByDeactivation(w *kueue.Workload) bool {
 	cond := apimeta.FindStatusCondition(w.Status.Conditions, kueue.WorkloadEvicted)
-	return cond != nil && cond.Status == metav1.ConditionTrue &&
-		(strings.HasPrefix(cond.Reason, kueue.WorkloadDeactivated) || strings.HasPrefix(cond.Reason, kueue.WorkloadEvictedByDeactivation))
+	return cond != nil && cond.Status == metav1.ConditionTrue && strings.HasPrefix(cond.Reason, kueue.WorkloadDeactivated)
 }
 
 func IsEvictedByPodsReadyTimeout(w *kueue.Workload) (*metav1.Condition, bool) {
@@ -843,7 +847,7 @@ func RemoveFinalizer(ctx context.Context, c client.Client, wl *kueue.Workload) e
 
 // AdmissionChecksForWorkload returns AdmissionChecks that should be assigned to a specific Workload based on
 // ClusterQueue configuration and ResourceFlavors
-func AdmissionChecksForWorkload(log logr.Logger, wl *kueue.Workload, admissionChecks map[string]sets.Set[kueue.ResourceFlavorReference]) sets.Set[string] {
+func AdmissionChecksForWorkload(log logr.Logger, wl *kueue.Workload, admissionChecks map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference]) sets.Set[kueue.AdmissionCheckReference] {
 	// If all admissionChecks should be run for all flavors we don't need to wait for Workload's Admission to be set.
 	// This is also the case if admissionChecks are specified with ClusterQueue.Spec.AdmissionChecks instead of
 	// ClusterQueue.Spec.AdmissionCheckStrategy
@@ -872,7 +876,7 @@ func AdmissionChecksForWorkload(log logr.Logger, wl *kueue.Workload, admissionCh
 		}
 	}
 
-	acNames := sets.New[string]()
+	acNames := sets.New[kueue.AdmissionCheckReference]()
 	for acName, flavors := range admissionChecks {
 		if len(flavors) == 0 {
 			acNames.Insert(acName)
diff --git a/site/content/en/docs/concepts/cohort.md b/site/content/en/docs/concepts/cohort.md
new file mode 100644
index 000000000..b8e8efdec
--- /dev/null
+++ b/site/content/en/docs/concepts/cohort.md
@@ -0,0 +1,100 @@
+---
+title: "Cohort"
+date: 2025-04-16
+weight: 4
+description: >
+  A cluster-scoped resource for organizing quotas
+---
+
+## Hello, Cohorts
+Cohorts give you the ability to organize your Quotas. ClusterQueues within the same Cohort (or same CohortTree for [Hieararchical Cohorts](#hierarchical-cohorts)) can share resources with each other. The simplest possible Cohort is the following:
+
+```yaml
+apiVersion: kueue.x-k8s.io/v1alpha1
+kind: Cohort
+metadata:
+  name: "hello-cohort"
+```
+
+A ClusterQueue may join this Cohort by referencing it:
+```yaml
+apiVersion: kueue.x-k8s.io/v1beta1
+kind: ClusterQueue
+metadata:
+  name: "my-cluster-queue"
+spec:
+  cohort: "hello-cohort"
+```
+
+## Configuring Quotas
+
+Similarly to [ClusterQueues](/docs/concepts/cluster_queue/#flavors-and-resources) Resource quotas may be defined at the Cohort level, and consumed by ClusterQueues within the Cohort.
+
+```yaml
+apiVersion: kueue.x-k8s.io/v1alpha1
+kind: Cohort
+metadata:
+  name: "hello-cohort"
+spec:
+  resourceGroups:
+    - coveredResources: ["cpu"]
+      flavors:
+      - name: "default-flavor"
+        resources:
+        - name: "cpu"
+          nominalQuota: 12
+```
+
+In order for a ClusterQueue to borrow resources from its Cohort, it **must**
+define nominal quota for the desired Resource and Flavor -  even if this value is 0.
+
+```yaml
+apiVersion: kueue.x-k8s.io/v1beta1
+kind: ClusterQueue
+metadata:
+  name: "my-cluster-queue"
+spec:
+  cohort: "hello-cohort"
+  resourceGroups:
+  - coveredResources: ["cpu"]
+    flavors:
+    - name: "default-flavor"
+      resources:
+      - name: "cpu"
+        nominalQuota: 0
+```
+
+## Hierarchical Cohorts
+Cohorts may be organized in a tree structure. We refer to the grouping of ClusterQueues and Cohorts that are part of the same tree as a **CohortTree**.
+
+ClusterQueues within a given CohortTree may use resources within it,
+subject to [Borrowing and Lending limits](/docs/reference/kueue.v1beta1/#kueue-x-k8s-io-v1beta1-ResourceQuota).
+These Borrowing and Lending Limits can be specified for Cohorts, as well as for ClusterQueues.
+
+Here is a simple CohortTree, with three Cohorts:
+```yaml
+apiVersion: kueue.x-k8s.io/v1alpha1
+kind: Cohort
+metadata:
+  name: "root-cohort"
+---
+apiVersion: kueue.x-k8s.io/v1alpha1
+kind: Cohort
+metadata:
+  name: "important-org"
+spec:
+  parent: "root-cohort"
+  fairSharing:
+    weight: "0.75"
+---
+apiVersion: kueue.x-k8s.io/v1alpha1
+kind: Cohort
+metadata:
+  name: "regular-org"
+spec:
+  parent: "root-cohort"
+  fairSharing:
+    weight: "0.25"
+```
+
+This example assumes that Fair Sharing is enabled. In this case, the important org will trend towards using 75% of common resources, while the regular org towards using 25%.
diff --git a/site/content/en/docs/concepts/multikueue.md b/site/content/en/docs/concepts/multikueue.md
index b41e505f3..f2c198434 100644
--- a/site/content/en/docs/concepts/multikueue.md
+++ b/site/content/en/docs/concepts/multikueue.md
@@ -78,7 +78,7 @@ On the other hand, the Worker cluster should install the full kubeflow operator.
 
 ## Plain Pods
 
-MultiKueue supports the remote creation and management of Plain Pods.
+MultiKueue supports the remote creation and management of Plain Pods and Group of Pods.
 
 ## Deployments
 
diff --git a/site/content/en/docs/installation/_index.md b/site/content/en/docs/installation/_index.md
index 798d9dade..07657d2d5 100644
--- a/site/content/en/docs/installation/_index.md
+++ b/site/content/en/docs/installation/_index.md
@@ -28,7 +28,7 @@ description: >
 
 Make sure the following conditions are met:
 
-- A Kubernetes cluster with version 1.25 or newer is running. Learn how to [install the Kubernetes tools](https://kubernetes.io/docs/tasks/tools/).
+- A Kubernetes cluster with version 1.29 or newer is running. Learn how to [install the Kubernetes tools](https://kubernetes.io/docs/tasks/tools/).
 - The `SuspendJob` [feature gate][feature_gate] is enabled. In Kubernetes 1.22 or newer, the feature gate is enabled by default.
 - (Optional) The `JobMutableNodeSchedulingDirectives` [feature gate][feature_gate] (available in Kubernetes 1.22 or newer) is enabled.
   In Kubernetes 1.23 or newer, the feature gate is enabled by default.
@@ -294,8 +294,6 @@ spec:
 |---------------------------------------|---------|------------|-------|-------|
 | `QueueVisibility`                     | `false` | Alpha      | 0.4   | 0.9   |
 | `QueueVisibility`                     | `false` | Deprecated | 0.9   |       |
-| `AdmissionCheckValidationRules`       | `false` | Deprecated | 0.9   |       |
-| `KeepQuotaForProvReqRetry`            | `false` | Deprecated | 0.9   |       |
 | `MultiplePreemptions`                 | `false` | Alpha      | 0.8   | 0.8   |
 | `MultiplePreemptions`                 | `true`  | Beta       | 0.9   | 0.9   |
 | `MultiplePreemptions`                 | `true`  | GA         | 0.10  |       |
diff --git a/site/content/en/docs/overview/_index.md b/site/content/en/docs/overview/_index.md
index 86f063320..98e37e036 100644
--- a/site/content/en/docs/overview/_index.md
+++ b/site/content/en/docs/overview/_index.md
@@ -25,7 +25,7 @@ A core design principle for Kueue is to avoid duplicating mature functionality i
 ## Features overview
 
 - **Job management:** Support job queueing based on [priorities](/docs/concepts/workload/#priority) with different [strategies](/docs/concepts/cluster_queue/#queueing-strategy): `StrictFIFO` and `BestEffortFIFO`.
-- **Advanced Resource management:** Comprising: [resource flavor fungibility](/docs/concepts/cluster_queue/#flavorfungibility), [Fair Sharing](/docs/concepts/preemption/#fair-sharing), [cohorts](/docs/concepts/cluster_queue/#cohort) and [preemption](/docs/concepts/cluster_queue/#preemption) with a variety of policies between different tenants.
+- **Advanced Resource management:** Comprising: [resource flavor fungibility](/docs/concepts/cluster_queue/#flavorfungibility), [Fair Sharing](/docs/concepts/preemption/#fair-sharing), [Cohorts](/docs/concepts/cohort) and [preemption](/docs/concepts/cluster_queue/#preemption) with a variety of policies between different tenants.
 - **Integrations:** Built-in support for popular jobs, e.g. [BatchJob](/docs/tasks/run/jobs/), [Kubeflow training jobs](/docs/tasks/run/kubeflow/), [RayJob](/docs/tasks/run/rayjobs/), [RayCluster](/docs/tasks/run/rayclusters/), [JobSet](/docs/tasks/run/jobsets/),  [AppWrappers](/docs/tasks/run/appwrappers/), [plain Pod and Pod Groups](/docs/tasks/run/plain_pods/).
 - **System insight:** Build-in [prometheus metrics](/docs/reference/metrics/) to help monitor the state of the system, and on-demand visibility endpoint for [monitoring of pending workloads](/docs/tasks/manage/monitor_pending_workloads/pending_workloads_on_demand/).
 - **AdmissionChecks:** A mechanism for internal or external components to influence whether a workload can be [admitted](/docs/concepts/admission_check/).
diff --git a/site/content/en/docs/reference/kueue.v1beta1.md b/site/content/en/docs/reference/kueue.v1beta1.md
index 85c950a00..49e77dd03 100644
--- a/site/content/en/docs/reference/kueue.v1beta1.md
+++ b/site/content/en/docs/reference/kueue.v1beta1.md
@@ -374,6 +374,24 @@ when this workloadPriorityClass should be used.</p>
 </tbody>
 </table>
 
+## `AdmissionCheckReference`     {#kueue-x-k8s-io-v1beta1-AdmissionCheckReference}
+    
+(Alias of `string`)
+
+**Appears in:**
+
+- [AdmissionCheckState](#kueue-x-k8s-io-v1beta1-AdmissionCheckState)
+
+- [AdmissionCheckStrategyRule](#kueue-x-k8s-io-v1beta1-AdmissionCheckStrategyRule)
+
+- [ClusterQueueSpec](#kueue-x-k8s-io-v1beta1-ClusterQueueSpec)
+
+
+<p>AdmissionCheckReference is the name of an AdmissionCheck.</p>
+
+
+
+
 ## `AdmissionCheckSpec`     {#kueue-x-k8s-io-v1beta1-AdmissionCheckSpec}
     
 
@@ -434,7 +452,7 @@ check.</p>
     
   
 <tr><td><code>name</code> <B>[Required]</B><br/>
-<code>string</code>
+<a href="#kueue-x-k8s-io-v1beta1-AdmissionCheckReference"><code>AdmissionCheckReference</code></a>
 </td>
 <td>
    <p>name identifies the admission check.</p>
@@ -516,7 +534,7 @@ current state.</p>
     
   
 <tr><td><code>name</code> <B>[Required]</B><br/>
-<code>string</code>
+<a href="#kueue-x-k8s-io-v1beta1-AdmissionCheckReference"><code>AdmissionCheckReference</code></a>
 </td>
 <td>
    <p>name is an AdmissionCheck's name.</p>
@@ -879,7 +897,7 @@ before borrowing or preempting in the flavor being evaluated.</p>
    <span class="text-muted">No description provided.</span></td>
 </tr>
 <tr><td><code>admissionChecks</code><br/>
-<code>[]string</code>
+<a href="#kueue-x-k8s-io-v1beta1-AdmissionCheckReference"><code>[]AdmissionCheckReference</code></a>
 </td>
 <td>
    <p>admissionChecks lists the AdmissionChecks required by this ClusterQueue.
diff --git a/site/content/en/docs/talks_and_presentations/_index.md b/site/content/en/docs/talks_and_presentations/_index.md
index ea9ee25a3..dc443fa76 100644
--- a/site/content/en/docs/talks_and_presentations/_index.md
+++ b/site/content/en/docs/talks_and_presentations/_index.md
@@ -9,6 +9,23 @@ description: >
   Talks and presentations showcasing Kueue
 ---
 
+# 2025
+
+* KubeCon EU, April, London<br>
+  Accelerate Your AI/ML Workloads With Topology-Aware Scheduling in Kueue<br>
+  Michał Woźniak, Google & Yuki Iwai, CyberAgent, Inc.<br>
+  [talk details](https://sched.co/1u5fo) | [video](https://youtu.be/F55pFM1M1bU)<br>
+
+* KubeCon EU, April, London<br>
+  Tutorial: Build, Operate, and Use a Multi-Tenant AI Cluster Based Entirely on Open Source<br>
+  Claudia Misale, Olivier Tardieu, & David Grove, IBM Research<br>
+  [talk details](https://sched.co/1tx6h) | [video](https://youtu.be/Ab7mRoJYsMo) | [tutorial materials](https://github.com/project-codeflare/mlbatch/tree/main/setup.KubeConEU25)<br>
+
+* KubeCon EU, April, London<br>
+  Kueue: Save Some QPS for the Rest of Us! How To Manage 100k Updates Per Second<br>
+  Patryk Bundyra, Google<br>
+  [talk details](https://sched.co/1txCn) | [video](https://youtu.be/njNXlZNT3dw)<br>
+
 # 2024
 
 * KubeCon NA, November, Salt Lake City<br>
diff --git a/site/content/en/docs/tasks/manage/monitor_pending_workloads/pending_workloads_on_demand.md b/site/content/en/docs/tasks/manage/monitor_pending_workloads/pending_workloads_on_demand.md
index 434b05f9f..e635e60f5 100644
--- a/site/content/en/docs/tasks/manage/monitor_pending_workloads/pending_workloads_on_demand.md
+++ b/site/content/en/docs/tasks/manage/monitor_pending_workloads/pending_workloads_on_demand.md
@@ -22,14 +22,6 @@ Make sure the following conditions are met:
 - The kubectl command-line tool has communication with your cluster.
 - [Kueue is installed](/docs/installation) in version v0.6.0 or later.
 
-### Configure API Priority and Fairness:
-
-To install the [API Priority and Fairness](https://kubernetes.io/docs/concepts/cluster-administration/flow-control/) configuration for the visibility API apply manifests:
-
-```shell
-kubectl apply --server-side -f https://github.com/kubernetes-sigs/kueue/releases/download/{{< param "version" >}}/visibility-apf.yaml
-```
-
 ### Directly accessing the Visibility API
 
 If you want to directly access the Visibility API with a http client like 
diff --git a/site/content/en/docs/tasks/run/external_workloads/argo_workflow.md b/site/content/en/docs/tasks/run/external_workloads/argo_workflow.md
index b31c83bdb..a9008234b 100644
--- a/site/content/en/docs/tasks/run/external_workloads/argo_workflow.md
+++ b/site/content/en/docs/tasks/run/external_workloads/argo_workflow.md
@@ -34,7 +34,7 @@ it should be specified in the `spec.podMetadata` section of the Workflow configu
 
 ### b. Targeting a different LocalQueue per template
 
-If prefer to target a different [local queue](/docs/concepts/local_queue) for each step of your Workflow,
+If you prefer to target a different [local queue](/docs/concepts/local_queue) for each step of your Workflow,
 you can define the queue in the `spec.templates[].metadata` section of the Workflow configuration.
 
 In this example `hello1` and `hello2a` will target `user-queue` and `hello2b` will
diff --git a/site/content/en/docs/tasks/run/multikueue/plain_pods.md b/site/content/en/docs/tasks/run/multikueue/plain_pods.md
index becdde494..ea1f93f28 100644
--- a/site/content/en/docs/tasks/run/multikueue/plain_pods.md
+++ b/site/content/en/docs/tasks/run/multikueue/plain_pods.md
@@ -20,6 +20,10 @@ Pods created on the manager cluster are automatically gated and receive live sta
 
 ## Example
 
-Once the setup is complete you can test it by running the example below:
+Once the setup is complete you can test it by running the examples below:
 
+1. Single plain pod
 {{< include "examples/pods-kueue/kueue-pod.yaml" "yaml" >}}
+
+2. Group of pods
+{{< include "examples/pods-kueue/kueue-pod-group.yaml" "yaml" >}}
\ No newline at end of file
diff --git a/site/content/en/docs/tasks/run/rayclusters.md b/site/content/en/docs/tasks/run/rayclusters.md
index 72eb66e3f..5afed9d4a 100644
--- a/site/content/en/docs/tasks/run/rayclusters.md
+++ b/site/content/en/docs/tasks/run/rayclusters.md
@@ -7,7 +7,7 @@ description: >
   Run a RayCluster on Kueue.
 ---
 
-This page shows how to leverage Kueue's scheduling and resource management capabilities when running [RayCluster](https://docs.ray.io/en/latest/cluster/getting-started.html).
+This page shows how to leverage Kueue's scheduling and resource management capabilities when running [RayCluster](https://docs.ray.io/en/latest/cluster/kubernetes/getting-started/raycluster-quick-start.html).
 
 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).
 
@@ -17,16 +17,16 @@ This guide is for [batch users](/docs/tasks#batch-user) that have a basic unders
 
 2. Check [Administer cluster quotas](/docs/tasks/manage/administer_cluster_quotas) for details on the initial Kueue setup.
 
-3. See [KubeRay Installation](https://ray-project.github.io/kuberay/deploy/installation/) for installation and configuration details of KubeRay.
+3. See [KubeRay Installation](https://docs.ray.io/en/latest/cluster/kubernetes/getting-started/raycluster-quick-start.html#step-2-deploy-a-kuberay-operator) for installation and configuration details of KubeRay.
 
 {{% alert title="Note" color="primary" %}}
 In order to use RayCluster, prior to v0.8.1, you need to restart Kueue after the installation.
-You can do it by running: `kubectl delete pods -lcontrol-plane=controller-manager -nkueue-system`.
+You can do it by running: `kubectl delete pods -l control-plane=controller-manager -n kueue-system`.
 {{% /alert %}}
 
 ## RayCluster definition
 
-When running [RayClusters](https://docs.ray.io/en/latest/cluster/getting-started.html) on
+When running [RayClusters](https://docs.ray.io/en/latest/cluster/kubernetes/getting-started/raycluster-quick-start.html) on
 Kueue, take into consideration the following aspects:
 
 ### a. Queue selection
diff --git a/site/content/en/docs/tasks/run/rayjobs.md b/site/content/en/docs/tasks/run/rayjobs.md
index 9f82375c2..d05e99c34 100644
--- a/site/content/en/docs/tasks/run/rayjobs.md
+++ b/site/content/en/docs/tasks/run/rayjobs.md
@@ -7,8 +7,8 @@ description: >
   Run a Kueue scheduled RayJob.
 ---
 
-This page shows how to leverage Kueue's scheduling and resource management capabilities when running [KubeRay's](https://ray-project.github.io/kuberay/)
-[RayJob](https://ray-project.github.io/kuberay/guidance/rayjob/).
+This page shows how to leverage Kueue's scheduling and resource management capabilities when running [KubeRay's](https://github.com/ray-project/kuberay)
+[RayJob](https://docs.ray.io/en/latest/cluster/kubernetes/getting-started/rayjob-quick-start.html).
 
 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).
 
@@ -18,16 +18,16 @@ This guide is for [batch users](/docs/tasks#batch-user) that have a basic unders
 
 2. Check [Administer cluster quotas](/docs/tasks/manage/administer_cluster_quotas) for details on the initial Kueue setup.
 
-3. See [KubeRay Installation](https://ray-project.github.io/kuberay/deploy/installation/) for installation and configuration details of KubeRay.
+3. See [KubeRay Installation](https://docs.ray.io/en/latest/cluster/kubernetes/getting-started/raycluster-quick-start.html#step-2-deploy-a-kuberay-operator) for installation and configuration details of KubeRay.
 
 {{% alert title="Note" color="primary" %}}
 In order to use RayJob, prior to v0.8.1, you need to restart Kueue after the installation.
-You can do it by running: `kubectl delete pods -lcontrol-plane=controller-manager -nkueue-system`.
+You can do it by running: `kubectl delete pods -l control-plane=controller-manager -n kueue-system`.
 {{% /alert %}}
 
 ## RayJob definition
 
-When running [RayJobs](https://ray-project.github.io/kuberay/guidance/rayjob/) on
+When running [RayJobs](https://docs.ray.io/en/latest/cluster/kubernetes/getting-started/rayjob-quick-start.html) on
 Kueue, take into consideration the following aspects:
 
 ### a. Queue selection
diff --git a/vendor/golang.org/x/net/html/atom/table.go b/vendor/golang.org/x/net/html/atom/table.go
index 2a938864c..b460e6f72 100644
--- a/vendor/golang.org/x/net/html/atom/table.go
+++ b/vendor/golang.org/x/net/html/atom/table.go
@@ -11,23 +11,23 @@ const (
 	AcceptCharset             Atom = 0x1a0e
 	Accesskey                 Atom = 0x2c09
 	Acronym                   Atom = 0xaa07
-	Action                    Atom = 0x27206
-	Address                   Atom = 0x6f307
+	Action                    Atom = 0x26506
+	Address                   Atom = 0x6f107
 	Align                     Atom = 0xb105
-	Allowfullscreen           Atom = 0x2080f
+	Allowfullscreen           Atom = 0x3280f
 	Allowpaymentrequest       Atom = 0xc113
 	Allowusermedia            Atom = 0xdd0e
 	Alt                       Atom = 0xf303
 	Annotation                Atom = 0x1c90a
 	AnnotationXml             Atom = 0x1c90e
-	Applet                    Atom = 0x31906
-	Area                      Atom = 0x35604
-	Article                   Atom = 0x3fc07
+	Applet                    Atom = 0x30806
+	Area                      Atom = 0x35004
+	Article                   Atom = 0x3f607
 	As                        Atom = 0x3c02
 	Aside                     Atom = 0x10705
 	Async                     Atom = 0xff05
 	Audio                     Atom = 0x11505
-	Autocomplete              Atom = 0x2780c
+	Autocomplete              Atom = 0x26b0c
 	Autofocus                 Atom = 0x12109
 	Autoplay                  Atom = 0x13c08
 	B                         Atom = 0x101
@@ -43,34 +43,34 @@ const (
 	Br                        Atom = 0x202
 	Button                    Atom = 0x19106
 	Canvas                    Atom = 0x10306
-	Caption                   Atom = 0x23107
-	Center                    Atom = 0x22006
-	Challenge                 Atom = 0x29b09
+	Caption                   Atom = 0x22407
+	Center                    Atom = 0x21306
+	Challenge                 Atom = 0x28e09
 	Charset                   Atom = 0x2107
-	Checked                   Atom = 0x47907
+	Checked                   Atom = 0x5b507
 	Cite                      Atom = 0x19c04
-	Class                     Atom = 0x56405
-	Code                      Atom = 0x5c504
+	Class                     Atom = 0x55805
+	Code                      Atom = 0x5ee04
 	Col                       Atom = 0x1ab03
 	Colgroup                  Atom = 0x1ab08
 	Color                     Atom = 0x1bf05
 	Cols                      Atom = 0x1c404
 	Colspan                   Atom = 0x1c407
 	Command                   Atom = 0x1d707
-	Content                   Atom = 0x58b07
-	Contenteditable           Atom = 0x58b0f
-	Contextmenu               Atom = 0x3800b
+	Content                   Atom = 0x57b07
+	Contenteditable           Atom = 0x57b0f
+	Contextmenu               Atom = 0x37a0b
 	Controls                  Atom = 0x1de08
-	Coords                    Atom = 0x1ea06
-	Crossorigin               Atom = 0x1fb0b
-	Data                      Atom = 0x4a504
-	Datalist                  Atom = 0x4a508
-	Datetime                  Atom = 0x2b808
-	Dd                        Atom = 0x2d702
+	Coords                    Atom = 0x1f006
+	Crossorigin               Atom = 0x1fa0b
+	Data                      Atom = 0x49904
+	Datalist                  Atom = 0x49908
+	Datetime                  Atom = 0x2ab08
+	Dd                        Atom = 0x2bf02
 	Default                   Atom = 0x10a07
-	Defer                     Atom = 0x5c705
-	Del                       Atom = 0x45203
-	Desc                      Atom = 0x56104
+	Defer                     Atom = 0x5f005
+	Del                       Atom = 0x44c03
+	Desc                      Atom = 0x55504
 	Details                   Atom = 0x7207
 	Dfn                       Atom = 0x8703
 	Dialog                    Atom = 0xbb06
@@ -78,106 +78,106 @@ const (
 	Dirname                   Atom = 0x9307
 	Disabled                  Atom = 0x16408
 	Div                       Atom = 0x16b03
-	Dl                        Atom = 0x5e602
-	Download                  Atom = 0x46308
+	Dl                        Atom = 0x5d602
+	Download                  Atom = 0x45d08
 	Draggable                 Atom = 0x17a09
-	Dropzone                  Atom = 0x40508
-	Dt                        Atom = 0x64b02
+	Dropzone                  Atom = 0x3ff08
+	Dt                        Atom = 0x64002
 	Em                        Atom = 0x6e02
 	Embed                     Atom = 0x6e05
-	Enctype                   Atom = 0x28d07
-	Face                      Atom = 0x21e04
-	Fieldset                  Atom = 0x22608
-	Figcaption                Atom = 0x22e0a
-	Figure                    Atom = 0x24806
+	Enctype                   Atom = 0x28007
+	Face                      Atom = 0x21104
+	Fieldset                  Atom = 0x21908
+	Figcaption                Atom = 0x2210a
+	Figure                    Atom = 0x23b06
 	Font                      Atom = 0x3f04
 	Footer                    Atom = 0xf606
-	For                       Atom = 0x25403
-	ForeignObject             Atom = 0x2540d
-	Foreignobject             Atom = 0x2610d
-	Form                      Atom = 0x26e04
-	Formaction                Atom = 0x26e0a
-	Formenctype               Atom = 0x2890b
-	Formmethod                Atom = 0x2a40a
-	Formnovalidate            Atom = 0x2ae0e
-	Formtarget                Atom = 0x2c00a
+	For                       Atom = 0x24703
+	ForeignObject             Atom = 0x2470d
+	Foreignobject             Atom = 0x2540d
+	Form                      Atom = 0x26104
+	Formaction                Atom = 0x2610a
+	Formenctype               Atom = 0x27c0b
+	Formmethod                Atom = 0x2970a
+	Formnovalidate            Atom = 0x2a10e
+	Formtarget                Atom = 0x2b30a
 	Frame                     Atom = 0x8b05
 	Frameset                  Atom = 0x8b08
 	H1                        Atom = 0x15c02
-	H2                        Atom = 0x2de02
-	H3                        Atom = 0x30d02
-	H4                        Atom = 0x34502
-	H5                        Atom = 0x34f02
-	H6                        Atom = 0x64d02
-	Head                      Atom = 0x33104
-	Header                    Atom = 0x33106
-	Headers                   Atom = 0x33107
+	H2                        Atom = 0x56102
+	H3                        Atom = 0x2cd02
+	H4                        Atom = 0x2fc02
+	H5                        Atom = 0x33f02
+	H6                        Atom = 0x34902
+	Head                      Atom = 0x32004
+	Header                    Atom = 0x32006
+	Headers                   Atom = 0x32007
 	Height                    Atom = 0x5206
-	Hgroup                    Atom = 0x2ca06
-	Hidden                    Atom = 0x2d506
-	High                      Atom = 0x2db04
+	Hgroup                    Atom = 0x64206
+	Hidden                    Atom = 0x2bd06
+	High                      Atom = 0x2ca04
 	Hr                        Atom = 0x15702
-	Href                      Atom = 0x2e004
-	Hreflang                  Atom = 0x2e008
+	Href                      Atom = 0x2cf04
+	Hreflang                  Atom = 0x2cf08
 	Html                      Atom = 0x5604
-	HttpEquiv                 Atom = 0x2e80a
+	HttpEquiv                 Atom = 0x2d70a
 	I                         Atom = 0x601
-	Icon                      Atom = 0x58a04
+	Icon                      Atom = 0x57a04
 	Id                        Atom = 0x10902
-	Iframe                    Atom = 0x2fc06
-	Image                     Atom = 0x30205
-	Img                       Atom = 0x30703
-	Input                     Atom = 0x44b05
-	Inputmode                 Atom = 0x44b09
-	Ins                       Atom = 0x20403
-	Integrity                 Atom = 0x23f09
+	Iframe                    Atom = 0x2eb06
+	Image                     Atom = 0x2f105
+	Img                       Atom = 0x2f603
+	Input                     Atom = 0x44505
+	Inputmode                 Atom = 0x44509
+	Ins                       Atom = 0x20303
+	Integrity                 Atom = 0x23209
 	Is                        Atom = 0x16502
-	Isindex                   Atom = 0x30f07
-	Ismap                     Atom = 0x31605
-	Itemid                    Atom = 0x38b06
+	Isindex                   Atom = 0x2fe07
+	Ismap                     Atom = 0x30505
+	Itemid                    Atom = 0x38506
 	Itemprop                  Atom = 0x19d08
-	Itemref                   Atom = 0x3cd07
-	Itemscope                 Atom = 0x67109
-	Itemtype                  Atom = 0x31f08
+	Itemref                   Atom = 0x3c707
+	Itemscope                 Atom = 0x66f09
+	Itemtype                  Atom = 0x30e08
 	Kbd                       Atom = 0xb903
 	Keygen                    Atom = 0x3206
 	Keytype                   Atom = 0xd607
 	Kind                      Atom = 0x17704
 	Label                     Atom = 0x5905
-	Lang                      Atom = 0x2e404
+	Lang                      Atom = 0x2d304
 	Legend                    Atom = 0x18106
 	Li                        Atom = 0xb202
 	Link                      Atom = 0x17404
-	List                      Atom = 0x4a904
-	Listing                   Atom = 0x4a907
+	List                      Atom = 0x49d04
+	Listing                   Atom = 0x49d07
 	Loop                      Atom = 0x5d04
 	Low                       Atom = 0xc303
 	Main                      Atom = 0x1004
 	Malignmark                Atom = 0xb00a
-	Manifest                  Atom = 0x6d708
-	Map                       Atom = 0x31803
+	Manifest                  Atom = 0x6d508
+	Map                       Atom = 0x30703
 	Mark                      Atom = 0xb604
-	Marquee                   Atom = 0x32707
-	Math                      Atom = 0x32e04
-	Max                       Atom = 0x33d03
-	Maxlength                 Atom = 0x33d09
+	Marquee                   Atom = 0x31607
+	Math                      Atom = 0x31d04
+	Max                       Atom = 0x33703
+	Maxlength                 Atom = 0x33709
 	Media                     Atom = 0xe605
 	Mediagroup                Atom = 0xe60a
-	Menu                      Atom = 0x38704
-	Menuitem                  Atom = 0x38708
-	Meta                      Atom = 0x4b804
+	Menu                      Atom = 0x38104
+	Menuitem                  Atom = 0x38108
+	Meta                      Atom = 0x4ac04
 	Meter                     Atom = 0x9805
-	Method                    Atom = 0x2a806
-	Mglyph                    Atom = 0x30806
-	Mi                        Atom = 0x34702
-	Min                       Atom = 0x34703
-	Minlength                 Atom = 0x34709
-	Mn                        Atom = 0x2b102
+	Method                    Atom = 0x29b06
+	Mglyph                    Atom = 0x2f706
+	Mi                        Atom = 0x34102
+	Min                       Atom = 0x34103
+	Minlength                 Atom = 0x34109
+	Mn                        Atom = 0x2a402
 	Mo                        Atom = 0xa402
-	Ms                        Atom = 0x67402
-	Mtext                     Atom = 0x35105
-	Multiple                  Atom = 0x35f08
-	Muted                     Atom = 0x36705
+	Ms                        Atom = 0x67202
+	Mtext                     Atom = 0x34b05
+	Multiple                  Atom = 0x35908
+	Muted                     Atom = 0x36105
 	Name                      Atom = 0x9604
 	Nav                       Atom = 0x1303
 	Nobr                      Atom = 0x3704
@@ -185,101 +185,101 @@ const (
 	Noframes                  Atom = 0x8908
 	Nomodule                  Atom = 0xa208
 	Nonce                     Atom = 0x1a605
-	Noscript                  Atom = 0x21608
-	Novalidate                Atom = 0x2b20a
-	Object                    Atom = 0x26806
+	Noscript                  Atom = 0x2c208
+	Novalidate                Atom = 0x2a50a
+	Object                    Atom = 0x25b06
 	Ol                        Atom = 0x13702
 	Onabort                   Atom = 0x19507
-	Onafterprint              Atom = 0x2360c
-	Onautocomplete            Atom = 0x2760e
-	Onautocompleteerror       Atom = 0x27613
-	Onauxclick                Atom = 0x61f0a
-	Onbeforeprint             Atom = 0x69e0d
-	Onbeforeunload            Atom = 0x6e70e
-	Onblur                    Atom = 0x56d06
+	Onafterprint              Atom = 0x2290c
+	Onautocomplete            Atom = 0x2690e
+	Onautocompleteerror       Atom = 0x26913
+	Onauxclick                Atom = 0x6140a
+	Onbeforeprint             Atom = 0x69c0d
+	Onbeforeunload            Atom = 0x6e50e
+	Onblur                    Atom = 0x1ea06
 	Oncancel                  Atom = 0x11908
 	Oncanplay                 Atom = 0x14d09
 	Oncanplaythrough          Atom = 0x14d10
-	Onchange                  Atom = 0x41b08
-	Onclick                   Atom = 0x2f507
-	Onclose                   Atom = 0x36c07
-	Oncontextmenu             Atom = 0x37e0d
-	Oncopy                    Atom = 0x39106
-	Oncuechange               Atom = 0x3970b
-	Oncut                     Atom = 0x3a205
-	Ondblclick                Atom = 0x3a70a
-	Ondrag                    Atom = 0x3b106
-	Ondragend                 Atom = 0x3b109
-	Ondragenter               Atom = 0x3ba0b
-	Ondragexit                Atom = 0x3c50a
-	Ondragleave               Atom = 0x3df0b
-	Ondragover                Atom = 0x3ea0a
-	Ondragstart               Atom = 0x3f40b
-	Ondrop                    Atom = 0x40306
-	Ondurationchange          Atom = 0x41310
-	Onemptied                 Atom = 0x40a09
-	Onended                   Atom = 0x42307
-	Onerror                   Atom = 0x42a07
-	Onfocus                   Atom = 0x43107
-	Onhashchange              Atom = 0x43d0c
-	Oninput                   Atom = 0x44907
-	Oninvalid                 Atom = 0x45509
-	Onkeydown                 Atom = 0x45e09
-	Onkeypress                Atom = 0x46b0a
-	Onkeyup                   Atom = 0x48007
-	Onlanguagechange          Atom = 0x48d10
-	Onload                    Atom = 0x49d06
-	Onloadeddata              Atom = 0x49d0c
-	Onloadedmetadata          Atom = 0x4b010
-	Onloadend                 Atom = 0x4c609
-	Onloadstart               Atom = 0x4cf0b
-	Onmessage                 Atom = 0x4da09
-	Onmessageerror            Atom = 0x4da0e
-	Onmousedown               Atom = 0x4e80b
-	Onmouseenter              Atom = 0x4f30c
-	Onmouseleave              Atom = 0x4ff0c
-	Onmousemove               Atom = 0x50b0b
-	Onmouseout                Atom = 0x5160a
-	Onmouseover               Atom = 0x5230b
-	Onmouseup                 Atom = 0x52e09
-	Onmousewheel              Atom = 0x53c0c
-	Onoffline                 Atom = 0x54809
-	Ononline                  Atom = 0x55108
-	Onpagehide                Atom = 0x5590a
-	Onpageshow                Atom = 0x5730a
-	Onpaste                   Atom = 0x57f07
-	Onpause                   Atom = 0x59a07
-	Onplay                    Atom = 0x5a406
-	Onplaying                 Atom = 0x5a409
-	Onpopstate                Atom = 0x5ad0a
-	Onprogress                Atom = 0x5b70a
-	Onratechange              Atom = 0x5cc0c
-	Onrejectionhandled        Atom = 0x5d812
-	Onreset                   Atom = 0x5ea07
-	Onresize                  Atom = 0x5f108
-	Onscroll                  Atom = 0x60008
-	Onsecuritypolicyviolation Atom = 0x60819
-	Onseeked                  Atom = 0x62908
-	Onseeking                 Atom = 0x63109
-	Onselect                  Atom = 0x63a08
-	Onshow                    Atom = 0x64406
-	Onsort                    Atom = 0x64f06
-	Onstalled                 Atom = 0x65909
-	Onstorage                 Atom = 0x66209
-	Onsubmit                  Atom = 0x66b08
-	Onsuspend                 Atom = 0x67b09
+	Onchange                  Atom = 0x41508
+	Onclick                   Atom = 0x2e407
+	Onclose                   Atom = 0x36607
+	Oncontextmenu             Atom = 0x3780d
+	Oncopy                    Atom = 0x38b06
+	Oncuechange               Atom = 0x3910b
+	Oncut                     Atom = 0x39c05
+	Ondblclick                Atom = 0x3a10a
+	Ondrag                    Atom = 0x3ab06
+	Ondragend                 Atom = 0x3ab09
+	Ondragenter               Atom = 0x3b40b
+	Ondragexit                Atom = 0x3bf0a
+	Ondragleave               Atom = 0x3d90b
+	Ondragover                Atom = 0x3e40a
+	Ondragstart               Atom = 0x3ee0b
+	Ondrop                    Atom = 0x3fd06
+	Ondurationchange          Atom = 0x40d10
+	Onemptied                 Atom = 0x40409
+	Onended                   Atom = 0x41d07
+	Onerror                   Atom = 0x42407
+	Onfocus                   Atom = 0x42b07
+	Onhashchange              Atom = 0x4370c
+	Oninput                   Atom = 0x44307
+	Oninvalid                 Atom = 0x44f09
+	Onkeydown                 Atom = 0x45809
+	Onkeypress                Atom = 0x4650a
+	Onkeyup                   Atom = 0x47407
+	Onlanguagechange          Atom = 0x48110
+	Onload                    Atom = 0x49106
+	Onloadeddata              Atom = 0x4910c
+	Onloadedmetadata          Atom = 0x4a410
+	Onloadend                 Atom = 0x4ba09
+	Onloadstart               Atom = 0x4c30b
+	Onmessage                 Atom = 0x4ce09
+	Onmessageerror            Atom = 0x4ce0e
+	Onmousedown               Atom = 0x4dc0b
+	Onmouseenter              Atom = 0x4e70c
+	Onmouseleave              Atom = 0x4f30c
+	Onmousemove               Atom = 0x4ff0b
+	Onmouseout                Atom = 0x50a0a
+	Onmouseover               Atom = 0x5170b
+	Onmouseup                 Atom = 0x52209
+	Onmousewheel              Atom = 0x5300c
+	Onoffline                 Atom = 0x53c09
+	Ononline                  Atom = 0x54508
+	Onpagehide                Atom = 0x54d0a
+	Onpageshow                Atom = 0x5630a
+	Onpaste                   Atom = 0x56f07
+	Onpause                   Atom = 0x58a07
+	Onplay                    Atom = 0x59406
+	Onplaying                 Atom = 0x59409
+	Onpopstate                Atom = 0x59d0a
+	Onprogress                Atom = 0x5a70a
+	Onratechange              Atom = 0x5bc0c
+	Onrejectionhandled        Atom = 0x5c812
+	Onreset                   Atom = 0x5da07
+	Onresize                  Atom = 0x5e108
+	Onscroll                  Atom = 0x5f508
+	Onsecuritypolicyviolation Atom = 0x5fd19
+	Onseeked                  Atom = 0x61e08
+	Onseeking                 Atom = 0x62609
+	Onselect                  Atom = 0x62f08
+	Onshow                    Atom = 0x63906
+	Onsort                    Atom = 0x64d06
+	Onstalled                 Atom = 0x65709
+	Onstorage                 Atom = 0x66009
+	Onsubmit                  Atom = 0x66908
+	Onsuspend                 Atom = 0x67909
 	Ontimeupdate              Atom = 0x400c
-	Ontoggle                  Atom = 0x68408
-	Onunhandledrejection      Atom = 0x68c14
-	Onunload                  Atom = 0x6ab08
-	Onvolumechange            Atom = 0x6b30e
-	Onwaiting                 Atom = 0x6c109
-	Onwheel                   Atom = 0x6ca07
+	Ontoggle                  Atom = 0x68208
+	Onunhandledrejection      Atom = 0x68a14
+	Onunload                  Atom = 0x6a908
+	Onvolumechange            Atom = 0x6b10e
+	Onwaiting                 Atom = 0x6bf09
+	Onwheel                   Atom = 0x6c807
 	Open                      Atom = 0x1a304
 	Optgroup                  Atom = 0x5f08
-	Optimum                   Atom = 0x6d107
-	Option                    Atom = 0x6e306
-	Output                    Atom = 0x51d06
+	Optimum                   Atom = 0x6cf07
+	Option                    Atom = 0x6e106
+	Output                    Atom = 0x51106
 	P                         Atom = 0xc01
 	Param                     Atom = 0xc05
 	Pattern                   Atom = 0x6607
@@ -288,466 +288,468 @@ const (
 	Placeholder               Atom = 0x1310b
 	Plaintext                 Atom = 0x1b209
 	Playsinline               Atom = 0x1400b
-	Poster                    Atom = 0x2cf06
-	Pre                       Atom = 0x47003
-	Preload                   Atom = 0x48607
-	Progress                  Atom = 0x5b908
-	Prompt                    Atom = 0x53606
-	Public                    Atom = 0x58606
+	Poster                    Atom = 0x64706
+	Pre                       Atom = 0x46a03
+	Preload                   Atom = 0x47a07
+	Progress                  Atom = 0x5a908
+	Prompt                    Atom = 0x52a06
+	Public                    Atom = 0x57606
 	Q                         Atom = 0xcf01
 	Radiogroup                Atom = 0x30a
 	Rb                        Atom = 0x3a02
-	Readonly                  Atom = 0x35708
-	Referrerpolicy            Atom = 0x3d10e
-	Rel                       Atom = 0x48703
-	Required                  Atom = 0x24c08
+	Readonly                  Atom = 0x35108
+	Referrerpolicy            Atom = 0x3cb0e
+	Rel                       Atom = 0x47b03
+	Required                  Atom = 0x23f08
 	Reversed                  Atom = 0x8008
 	Rows                      Atom = 0x9c04
 	Rowspan                   Atom = 0x9c07
-	Rp                        Atom = 0x23c02
+	Rp                        Atom = 0x22f02
 	Rt                        Atom = 0x19a02
 	Rtc                       Atom = 0x19a03
 	Ruby                      Atom = 0xfb04
 	S                         Atom = 0x2501
 	Samp                      Atom = 0x7804
 	Sandbox                   Atom = 0x12907
-	Scope                     Atom = 0x67505
-	Scoped                    Atom = 0x67506
-	Script                    Atom = 0x21806
-	Seamless                  Atom = 0x37108
-	Section                   Atom = 0x56807
-	Select                    Atom = 0x63c06
-	Selected                  Atom = 0x63c08
-	Shape                     Atom = 0x1e505
-	Size                      Atom = 0x5f504
-	Sizes                     Atom = 0x5f505
-	Slot                      Atom = 0x1ef04
-	Small                     Atom = 0x20605
-	Sortable                  Atom = 0x65108
-	Sorted                    Atom = 0x33706
-	Source                    Atom = 0x37806
-	Spacer                    Atom = 0x43706
+	Scope                     Atom = 0x67305
+	Scoped                    Atom = 0x67306
+	Script                    Atom = 0x2c406
+	Seamless                  Atom = 0x36b08
+	Search                    Atom = 0x55c06
+	Section                   Atom = 0x1e507
+	Select                    Atom = 0x63106
+	Selected                  Atom = 0x63108
+	Shape                     Atom = 0x1f505
+	Size                      Atom = 0x5e504
+	Sizes                     Atom = 0x5e505
+	Slot                      Atom = 0x20504
+	Small                     Atom = 0x32605
+	Sortable                  Atom = 0x64f08
+	Sorted                    Atom = 0x37206
+	Source                    Atom = 0x43106
+	Spacer                    Atom = 0x46e06
 	Span                      Atom = 0x9f04
-	Spellcheck                Atom = 0x4740a
-	Src                       Atom = 0x5c003
-	Srcdoc                    Atom = 0x5c006
-	Srclang                   Atom = 0x5f907
-	Srcset                    Atom = 0x6f906
-	Start                     Atom = 0x3fa05
-	Step                      Atom = 0x58304
+	Spellcheck                Atom = 0x5b00a
+	Src                       Atom = 0x5e903
+	Srcdoc                    Atom = 0x5e906
+	Srclang                   Atom = 0x6f707
+	Srcset                    Atom = 0x6fe06
+	Start                     Atom = 0x3f405
+	Step                      Atom = 0x57304
 	Strike                    Atom = 0xd206
-	Strong                    Atom = 0x6dd06
-	Style                     Atom = 0x6ff05
-	Sub                       Atom = 0x66d03
-	Summary                   Atom = 0x70407
-	Sup                       Atom = 0x70b03
-	Svg                       Atom = 0x70e03
-	System                    Atom = 0x71106
-	Tabindex                  Atom = 0x4be08
-	Table                     Atom = 0x59505
-	Target                    Atom = 0x2c406
+	Strong                    Atom = 0x6db06
+	Style                     Atom = 0x70405
+	Sub                       Atom = 0x66b03
+	Summary                   Atom = 0x70907
+	Sup                       Atom = 0x71003
+	Svg                       Atom = 0x71303
+	System                    Atom = 0x71606
+	Tabindex                  Atom = 0x4b208
+	Table                     Atom = 0x58505
+	Target                    Atom = 0x2b706
 	Tbody                     Atom = 0x2705
 	Td                        Atom = 0x9202
-	Template                  Atom = 0x71408
-	Textarea                  Atom = 0x35208
+	Template                  Atom = 0x71908
+	Textarea                  Atom = 0x34c08
 	Tfoot                     Atom = 0xf505
 	Th                        Atom = 0x15602
-	Thead                     Atom = 0x33005
+	Thead                     Atom = 0x31f05
 	Time                      Atom = 0x4204
 	Title                     Atom = 0x11005
 	Tr                        Atom = 0xcc02
 	Track                     Atom = 0x1ba05
-	Translate                 Atom = 0x1f209
+	Translate                 Atom = 0x20809
 	Tt                        Atom = 0x6802
 	Type                      Atom = 0xd904
-	Typemustmatch             Atom = 0x2900d
+	Typemustmatch             Atom = 0x2830d
 	U                         Atom = 0xb01
 	Ul                        Atom = 0xa702
 	Updateviacache            Atom = 0x460e
-	Usemap                    Atom = 0x59e06
+	Usemap                    Atom = 0x58e06
 	Value                     Atom = 0x1505
 	Var                       Atom = 0x16d03
-	Video                     Atom = 0x2f105
-	Wbr                       Atom = 0x57c03
-	Width                     Atom = 0x64905
-	Workertype                Atom = 0x71c0a
-	Wrap                      Atom = 0x72604
+	Video                     Atom = 0x2e005
+	Wbr                       Atom = 0x56c03
+	Width                     Atom = 0x63e05
+	Workertype                Atom = 0x7210a
+	Wrap                      Atom = 0x72b04
 	Xmp                       Atom = 0x12f03
 )
 
-const hash0 = 0x81cdf10e
+const hash0 = 0x84f70e16
 
 const maxAtomLen = 25
 
 var table = [1 << 9]Atom{
-	0x1:   0xe60a,  // mediagroup
-	0x2:   0x2e404, // lang
-	0x4:   0x2c09,  // accesskey
-	0x5:   0x8b08,  // frameset
-	0x7:   0x63a08, // onselect
-	0x8:   0x71106, // system
-	0xa:   0x64905, // width
-	0xc:   0x2890b, // formenctype
-	0xd:   0x13702, // ol
-	0xe:   0x3970b, // oncuechange
-	0x10:  0x14b03, // bdo
-	0x11:  0x11505, // audio
-	0x12:  0x17a09, // draggable
-	0x14:  0x2f105, // video
-	0x15:  0x2b102, // mn
-	0x16:  0x38704, // menu
-	0x17:  0x2cf06, // poster
-	0x19:  0xf606,  // footer
-	0x1a:  0x2a806, // method
-	0x1b:  0x2b808, // datetime
-	0x1c:  0x19507, // onabort
-	0x1d:  0x460e,  // updateviacache
-	0x1e:  0xff05,  // async
-	0x1f:  0x49d06, // onload
-	0x21:  0x11908, // oncancel
-	0x22:  0x62908, // onseeked
-	0x23:  0x30205, // image
-	0x24:  0x5d812, // onrejectionhandled
-	0x26:  0x17404, // link
-	0x27:  0x51d06, // output
-	0x28:  0x33104, // head
-	0x29:  0x4ff0c, // onmouseleave
-	0x2a:  0x57f07, // onpaste
-	0x2b:  0x5a409, // onplaying
-	0x2c:  0x1c407, // colspan
-	0x2f:  0x1bf05, // color
-	0x30:  0x5f504, // size
-	0x31:  0x2e80a, // http-equiv
-	0x33:  0x601,   // i
-	0x34:  0x5590a, // onpagehide
-	0x35:  0x68c14, // onunhandledrejection
-	0x37:  0x42a07, // onerror
-	0x3a:  0x3b08,  // basefont
-	0x3f:  0x1303,  // nav
-	0x40:  0x17704, // kind
-	0x41:  0x35708, // readonly
-	0x42:  0x30806, // mglyph
-	0x44:  0xb202,  // li
-	0x46:  0x2d506, // hidden
-	0x47:  0x70e03, // svg
-	0x48:  0x58304, // step
-	0x49:  0x23f09, // integrity
-	0x4a:  0x58606, // public
-	0x4c:  0x1ab03, // col
-	0x4d:  0x1870a, // blockquote
-	0x4e:  0x34f02, // h5
-	0x50:  0x5b908, // progress
-	0x51:  0x5f505, // sizes
-	0x52:  0x34502, // h4
-	0x56:  0x33005, // thead
-	0x57:  0xd607,  // keytype
-	0x58:  0x5b70a, // onprogress
-	0x59:  0x44b09, // inputmode
-	0x5a:  0x3b109, // ondragend
-	0x5d:  0x3a205, // oncut
-	0x5e:  0x43706, // spacer
-	0x5f:  0x1ab08, // colgroup
-	0x62:  0x16502, // is
-	0x65:  0x3c02,  // as
-	0x66:  0x54809, // onoffline
-	0x67:  0x33706, // sorted
-	0x69:  0x48d10, // onlanguagechange
-	0x6c:  0x43d0c, // onhashchange
-	0x6d:  0x9604,  // name
-	0x6e:  0xf505,  // tfoot
-	0x6f:  0x56104, // desc
-	0x70:  0x33d03, // max
-	0x72:  0x1ea06, // coords
-	0x73:  0x30d02, // h3
-	0x74:  0x6e70e, // onbeforeunload
-	0x75:  0x9c04,  // rows
-	0x76:  0x63c06, // select
-	0x77:  0x9805,  // meter
-	0x78:  0x38b06, // itemid
-	0x79:  0x53c0c, // onmousewheel
-	0x7a:  0x5c006, // srcdoc
-	0x7d:  0x1ba05, // track
-	0x7f:  0x31f08, // itemtype
-	0x82:  0xa402,  // mo
-	0x83:  0x41b08, // onchange
-	0x84:  0x33107, // headers
-	0x85:  0x5cc0c, // onratechange
-	0x86:  0x60819, // onsecuritypolicyviolation
-	0x88:  0x4a508, // datalist
-	0x89:  0x4e80b, // onmousedown
-	0x8a:  0x1ef04, // slot
-	0x8b:  0x4b010, // onloadedmetadata
-	0x8c:  0x1a06,  // accept
-	0x8d:  0x26806, // object
-	0x91:  0x6b30e, // onvolumechange
-	0x92:  0x2107,  // charset
-	0x93:  0x27613, // onautocompleteerror
-	0x94:  0xc113,  // allowpaymentrequest
-	0x95:  0x2804,  // body
-	0x96:  0x10a07, // default
-	0x97:  0x63c08, // selected
-	0x98:  0x21e04, // face
-	0x99:  0x1e505, // shape
-	0x9b:  0x68408, // ontoggle
-	0x9e:  0x64b02, // dt
-	0x9f:  0xb604,  // mark
-	0xa1:  0xb01,   // u
-	0xa4:  0x6ab08, // onunload
-	0xa5:  0x5d04,  // loop
-	0xa6:  0x16408, // disabled
-	0xaa:  0x42307, // onended
-	0xab:  0xb00a,  // malignmark
-	0xad:  0x67b09, // onsuspend
-	0xae:  0x35105, // mtext
-	0xaf:  0x64f06, // onsort
-	0xb0:  0x19d08, // itemprop
-	0xb3:  0x67109, // itemscope
-	0xb4:  0x17305, // blink
-	0xb6:  0x3b106, // ondrag
-	0xb7:  0xa702,  // ul
-	0xb8:  0x26e04, // form
-	0xb9:  0x12907, // sandbox
-	0xba:  0x8b05,  // frame
-	0xbb:  0x1505,  // value
-	0xbc:  0x66209, // onstorage
-	0xbf:  0xaa07,  // acronym
-	0xc0:  0x19a02, // rt
-	0xc2:  0x202,   // br
-	0xc3:  0x22608, // fieldset
-	0xc4:  0x2900d, // typemustmatch
-	0xc5:  0xa208,  // nomodule
-	0xc6:  0x6c07,  // noembed
-	0xc7:  0x69e0d, // onbeforeprint
-	0xc8:  0x19106, // button
-	0xc9:  0x2f507, // onclick
-	0xca:  0x70407, // summary
-	0xcd:  0xfb04,  // ruby
-	0xce:  0x56405, // class
-	0xcf:  0x3f40b, // ondragstart
-	0xd0:  0x23107, // caption
-	0xd4:  0xdd0e,  // allowusermedia
-	0xd5:  0x4cf0b, // onloadstart
-	0xd9:  0x16b03, // div
-	0xda:  0x4a904, // list
-	0xdb:  0x32e04, // math
-	0xdc:  0x44b05, // input
-	0xdf:  0x3ea0a, // ondragover
-	0xe0:  0x2de02, // h2
-	0xe2:  0x1b209, // plaintext
-	0xe4:  0x4f30c, // onmouseenter
-	0xe7:  0x47907, // checked
-	0xe8:  0x47003, // pre
-	0xea:  0x35f08, // multiple
-	0xeb:  0xba03,  // bdi
-	0xec:  0x33d09, // maxlength
-	0xed:  0xcf01,  // q
-	0xee:  0x61f0a, // onauxclick
-	0xf0:  0x57c03, // wbr
-	0xf2:  0x3b04,  // base
-	0xf3:  0x6e306, // option
-	0xf5:  0x41310, // ondurationchange
-	0xf7:  0x8908,  // noframes
-	0xf9:  0x40508, // dropzone
-	0xfb:  0x67505, // scope
-	0xfc:  0x8008,  // reversed
-	0xfd:  0x3ba0b, // ondragenter
-	0xfe:  0x3fa05, // start
-	0xff:  0x12f03, // xmp
-	0x100: 0x5f907, // srclang
-	0x101: 0x30703, // img
-	0x104: 0x101,   // b
-	0x105: 0x25403, // for
-	0x106: 0x10705, // aside
-	0x107: 0x44907, // oninput
-	0x108: 0x35604, // area
-	0x109: 0x2a40a, // formmethod
-	0x10a: 0x72604, // wrap
-	0x10c: 0x23c02, // rp
-	0x10d: 0x46b0a, // onkeypress
-	0x10e: 0x6802,  // tt
-	0x110: 0x34702, // mi
-	0x111: 0x36705, // muted
-	0x112: 0xf303,  // alt
-	0x113: 0x5c504, // code
-	0x114: 0x6e02,  // em
-	0x115: 0x3c50a, // ondragexit
-	0x117: 0x9f04,  // span
-	0x119: 0x6d708, // manifest
-	0x11a: 0x38708, // menuitem
-	0x11b: 0x58b07, // content
-	0x11d: 0x6c109, // onwaiting
-	0x11f: 0x4c609, // onloadend
-	0x121: 0x37e0d, // oncontextmenu
-	0x123: 0x56d06, // onblur
-	0x124: 0x3fc07, // article
-	0x125: 0x9303,  // dir
-	0x126: 0xef04,  // ping
-	0x127: 0x24c08, // required
-	0x128: 0x45509, // oninvalid
-	0x129: 0xb105,  // align
-	0x12b: 0x58a04, // icon
-	0x12c: 0x64d02, // h6
-	0x12d: 0x1c404, // cols
-	0x12e: 0x22e0a, // figcaption
-	0x12f: 0x45e09, // onkeydown
-	0x130: 0x66b08, // onsubmit
-	0x131: 0x14d09, // oncanplay
-	0x132: 0x70b03, // sup
-	0x133: 0xc01,   // p
-	0x135: 0x40a09, // onemptied
-	0x136: 0x39106, // oncopy
-	0x137: 0x19c04, // cite
-	0x138: 0x3a70a, // ondblclick
-	0x13a: 0x50b0b, // onmousemove
-	0x13c: 0x66d03, // sub
-	0x13d: 0x48703, // rel
-	0x13e: 0x5f08,  // optgroup
-	0x142: 0x9c07,  // rowspan
-	0x143: 0x37806, // source
-	0x144: 0x21608, // noscript
-	0x145: 0x1a304, // open
-	0x146: 0x20403, // ins
-	0x147: 0x2540d, // foreignObject
-	0x148: 0x5ad0a, // onpopstate
-	0x14a: 0x28d07, // enctype
-	0x14b: 0x2760e, // onautocomplete
-	0x14c: 0x35208, // textarea
-	0x14e: 0x2780c, // autocomplete
-	0x14f: 0x15702, // hr
-	0x150: 0x1de08, // controls
-	0x151: 0x10902, // id
-	0x153: 0x2360c, // onafterprint
-	0x155: 0x2610d, // foreignobject
-	0x156: 0x32707, // marquee
-	0x157: 0x59a07, // onpause
-	0x158: 0x5e602, // dl
-	0x159: 0x5206,  // height
-	0x15a: 0x34703, // min
-	0x15b: 0x9307,  // dirname
-	0x15c: 0x1f209, // translate
-	0x15d: 0x5604,  // html
-	0x15e: 0x34709, // minlength
-	0x15f: 0x48607, // preload
-	0x160: 0x71408, // template
-	0x161: 0x3df0b, // ondragleave
-	0x162: 0x3a02,  // rb
-	0x164: 0x5c003, // src
-	0x165: 0x6dd06, // strong
-	0x167: 0x7804,  // samp
-	0x168: 0x6f307, // address
-	0x169: 0x55108, // ononline
-	0x16b: 0x1310b, // placeholder
-	0x16c: 0x2c406, // target
-	0x16d: 0x20605, // small
-	0x16e: 0x6ca07, // onwheel
-	0x16f: 0x1c90a, // annotation
-	0x170: 0x4740a, // spellcheck
-	0x171: 0x7207,  // details
-	0x172: 0x10306, // canvas
-	0x173: 0x12109, // autofocus
-	0x174: 0xc05,   // param
-	0x176: 0x46308, // download
-	0x177: 0x45203, // del
-	0x178: 0x36c07, // onclose
-	0x179: 0xb903,  // kbd
-	0x17a: 0x31906, // applet
-	0x17b: 0x2e004, // href
-	0x17c: 0x5f108, // onresize
-	0x17e: 0x49d0c, // onloadeddata
-	0x180: 0xcc02,  // tr
-	0x181: 0x2c00a, // formtarget
-	0x182: 0x11005, // title
-	0x183: 0x6ff05, // style
-	0x184: 0xd206,  // strike
-	0x185: 0x59e06, // usemap
-	0x186: 0x2fc06, // iframe
-	0x187: 0x1004,  // main
-	0x189: 0x7b07,  // picture
-	0x18c: 0x31605, // ismap
-	0x18e: 0x4a504, // data
-	0x18f: 0x5905,  // label
-	0x191: 0x3d10e, // referrerpolicy
-	0x192: 0x15602, // th
-	0x194: 0x53606, // prompt
-	0x195: 0x56807, // section
-	0x197: 0x6d107, // optimum
-	0x198: 0x2db04, // high
-	0x199: 0x15c02, // h1
-	0x19a: 0x65909, // onstalled
-	0x19b: 0x16d03, // var
-	0x19c: 0x4204,  // time
-	0x19e: 0x67402, // ms
-	0x19f: 0x33106, // header
-	0x1a0: 0x4da09, // onmessage
-	0x1a1: 0x1a605, // nonce
-	0x1a2: 0x26e0a, // formaction
-	0x1a3: 0x22006, // center
-	0x1a4: 0x3704,  // nobr
-	0x1a5: 0x59505, // table
-	0x1a6: 0x4a907, // listing
-	0x1a7: 0x18106, // legend
-	0x1a9: 0x29b09, // challenge
-	0x1aa: 0x24806, // figure
-	0x1ab: 0xe605,  // media
-	0x1ae: 0xd904,  // type
-	0x1af: 0x3f04,  // font
-	0x1b0: 0x4da0e, // onmessageerror
-	0x1b1: 0x37108, // seamless
-	0x1b2: 0x8703,  // dfn
-	0x1b3: 0x5c705, // defer
-	0x1b4: 0xc303,  // low
-	0x1b5: 0x19a03, // rtc
-	0x1b6: 0x5230b, // onmouseover
-	0x1b7: 0x2b20a, // novalidate
-	0x1b8: 0x71c0a, // workertype
-	0x1ba: 0x3cd07, // itemref
-	0x1bd: 0x1,     // a
-	0x1be: 0x31803, // map
-	0x1bf: 0x400c,  // ontimeupdate
-	0x1c0: 0x15e07, // bgsound
-	0x1c1: 0x3206,  // keygen
-	0x1c2: 0x2705,  // tbody
-	0x1c5: 0x64406, // onshow
-	0x1c7: 0x2501,  // s
-	0x1c8: 0x6607,  // pattern
-	0x1cc: 0x14d10, // oncanplaythrough
-	0x1ce: 0x2d702, // dd
-	0x1cf: 0x6f906, // srcset
-	0x1d0: 0x17003, // big
-	0x1d2: 0x65108, // sortable
-	0x1d3: 0x48007, // onkeyup
-	0x1d5: 0x5a406, // onplay
-	0x1d7: 0x4b804, // meta
-	0x1d8: 0x40306, // ondrop
-	0x1da: 0x60008, // onscroll
-	0x1db: 0x1fb0b, // crossorigin
-	0x1dc: 0x5730a, // onpageshow
-	0x1dd: 0x4,     // abbr
-	0x1de: 0x9202,  // td
-	0x1df: 0x58b0f, // contenteditable
-	0x1e0: 0x27206, // action
-	0x1e1: 0x1400b, // playsinline
-	0x1e2: 0x43107, // onfocus
-	0x1e3: 0x2e008, // hreflang
-	0x1e5: 0x5160a, // onmouseout
-	0x1e6: 0x5ea07, // onreset
-	0x1e7: 0x13c08, // autoplay
-	0x1e8: 0x63109, // onseeking
-	0x1ea: 0x67506, // scoped
-	0x1ec: 0x30a,   // radiogroup
-	0x1ee: 0x3800b, // contextmenu
-	0x1ef: 0x52e09, // onmouseup
-	0x1f1: 0x2ca06, // hgroup
-	0x1f2: 0x2080f, // allowfullscreen
-	0x1f3: 0x4be08, // tabindex
-	0x1f6: 0x30f07, // isindex
-	0x1f7: 0x1a0e,  // accept-charset
-	0x1f8: 0x2ae0e, // formnovalidate
-	0x1fb: 0x1c90e, // annotation-xml
-	0x1fc: 0x6e05,  // embed
-	0x1fd: 0x21806, // script
-	0x1fe: 0xbb06,  // dialog
-	0x1ff: 0x1d707, // command
+	0x1:   0x3ff08, // dropzone
+	0x2:   0x3b08,  // basefont
+	0x3:   0x23209, // integrity
+	0x4:   0x43106, // source
+	0x5:   0x2c09,  // accesskey
+	0x6:   0x1a06,  // accept
+	0x7:   0x6c807, // onwheel
+	0xb:   0x47407, // onkeyup
+	0xc:   0x32007, // headers
+	0xd:   0x67306, // scoped
+	0xe:   0x67909, // onsuspend
+	0xf:   0x8908,  // noframes
+	0x10:  0x1fa0b, // crossorigin
+	0x11:  0x2e407, // onclick
+	0x12:  0x3f405, // start
+	0x13:  0x37a0b, // contextmenu
+	0x14:  0x5e903, // src
+	0x15:  0x1c404, // cols
+	0x16:  0xbb06,  // dialog
+	0x17:  0x47a07, // preload
+	0x18:  0x3c707, // itemref
+	0x1b:  0x2f105, // image
+	0x1d:  0x4ba09, // onloadend
+	0x1e:  0x45d08, // download
+	0x1f:  0x46a03, // pre
+	0x23:  0x2970a, // formmethod
+	0x24:  0x71303, // svg
+	0x25:  0xcf01,  // q
+	0x26:  0x64002, // dt
+	0x27:  0x1de08, // controls
+	0x2a:  0x2804,  // body
+	0x2b:  0xd206,  // strike
+	0x2c:  0x3910b, // oncuechange
+	0x2d:  0x4c30b, // onloadstart
+	0x2e:  0x2fe07, // isindex
+	0x2f:  0xb202,  // li
+	0x30:  0x1400b, // playsinline
+	0x31:  0x34102, // mi
+	0x32:  0x30806, // applet
+	0x33:  0x4ce09, // onmessage
+	0x35:  0x13702, // ol
+	0x36:  0x1a304, // open
+	0x39:  0x14d09, // oncanplay
+	0x3a:  0x6bf09, // onwaiting
+	0x3b:  0x11908, // oncancel
+	0x3c:  0x6a908, // onunload
+	0x3e:  0x53c09, // onoffline
+	0x3f:  0x1a0e,  // accept-charset
+	0x40:  0x32004, // head
+	0x42:  0x3ab09, // ondragend
+	0x43:  0x1310b, // placeholder
+	0x44:  0x2b30a, // formtarget
+	0x45:  0x2540d, // foreignobject
+	0x47:  0x400c,  // ontimeupdate
+	0x48:  0xdd0e,  // allowusermedia
+	0x4a:  0x69c0d, // onbeforeprint
+	0x4b:  0x5604,  // html
+	0x4c:  0x9f04,  // span
+	0x4d:  0x64206, // hgroup
+	0x4e:  0x16408, // disabled
+	0x4f:  0x4204,  // time
+	0x51:  0x42b07, // onfocus
+	0x53:  0xb00a,  // malignmark
+	0x55:  0x4650a, // onkeypress
+	0x56:  0x55805, // class
+	0x57:  0x1ab08, // colgroup
+	0x58:  0x33709, // maxlength
+	0x59:  0x5a908, // progress
+	0x5b:  0x70405, // style
+	0x5c:  0x2a10e, // formnovalidate
+	0x5e:  0x38b06, // oncopy
+	0x60:  0x26104, // form
+	0x61:  0xf606,  // footer
+	0x64:  0x30a,   // radiogroup
+	0x66:  0xfb04,  // ruby
+	0x67:  0x4ff0b, // onmousemove
+	0x68:  0x19d08, // itemprop
+	0x69:  0x2d70a, // http-equiv
+	0x6a:  0x15602, // th
+	0x6c:  0x6e02,  // em
+	0x6d:  0x38108, // menuitem
+	0x6e:  0x63106, // select
+	0x6f:  0x48110, // onlanguagechange
+	0x70:  0x31f05, // thead
+	0x71:  0x15c02, // h1
+	0x72:  0x5e906, // srcdoc
+	0x75:  0x9604,  // name
+	0x76:  0x19106, // button
+	0x77:  0x55504, // desc
+	0x78:  0x17704, // kind
+	0x79:  0x1bf05, // color
+	0x7c:  0x58e06, // usemap
+	0x7d:  0x30e08, // itemtype
+	0x7f:  0x6d508, // manifest
+	0x81:  0x5300c, // onmousewheel
+	0x82:  0x4dc0b, // onmousedown
+	0x84:  0xc05,   // param
+	0x85:  0x2e005, // video
+	0x86:  0x4910c, // onloadeddata
+	0x87:  0x6f107, // address
+	0x8c:  0xef04,  // ping
+	0x8d:  0x24703, // for
+	0x8f:  0x62f08, // onselect
+	0x90:  0x30703, // map
+	0x92:  0xc01,   // p
+	0x93:  0x8008,  // reversed
+	0x94:  0x54d0a, // onpagehide
+	0x95:  0x3206,  // keygen
+	0x96:  0x34109, // minlength
+	0x97:  0x3e40a, // ondragover
+	0x98:  0x42407, // onerror
+	0x9a:  0x2107,  // charset
+	0x9b:  0x29b06, // method
+	0x9c:  0x101,   // b
+	0x9d:  0x68208, // ontoggle
+	0x9e:  0x2bd06, // hidden
+	0xa0:  0x3f607, // article
+	0xa2:  0x63906, // onshow
+	0xa3:  0x64d06, // onsort
+	0xa5:  0x57b0f, // contenteditable
+	0xa6:  0x66908, // onsubmit
+	0xa8:  0x44f09, // oninvalid
+	0xaa:  0x202,   // br
+	0xab:  0x10902, // id
+	0xac:  0x5d04,  // loop
+	0xad:  0x5630a, // onpageshow
+	0xb0:  0x2cf04, // href
+	0xb2:  0x2210a, // figcaption
+	0xb3:  0x2690e, // onautocomplete
+	0xb4:  0x49106, // onload
+	0xb6:  0x9c04,  // rows
+	0xb7:  0x1a605, // nonce
+	0xb8:  0x68a14, // onunhandledrejection
+	0xbb:  0x21306, // center
+	0xbc:  0x59406, // onplay
+	0xbd:  0x33f02, // h5
+	0xbe:  0x49d07, // listing
+	0xbf:  0x57606, // public
+	0xc2:  0x23b06, // figure
+	0xc3:  0x57a04, // icon
+	0xc4:  0x1ab03, // col
+	0xc5:  0x47b03, // rel
+	0xc6:  0xe605,  // media
+	0xc7:  0x12109, // autofocus
+	0xc8:  0x19a02, // rt
+	0xca:  0x2d304, // lang
+	0xcc:  0x49908, // datalist
+	0xce:  0x2eb06, // iframe
+	0xcf:  0x36105, // muted
+	0xd0:  0x6140a, // onauxclick
+	0xd2:  0x3c02,  // as
+	0xd6:  0x3fd06, // ondrop
+	0xd7:  0x1c90a, // annotation
+	0xd8:  0x21908, // fieldset
+	0xdb:  0x2cf08, // hreflang
+	0xdc:  0x4e70c, // onmouseenter
+	0xdd:  0x2a402, // mn
+	0xde:  0xe60a,  // mediagroup
+	0xdf:  0x9805,  // meter
+	0xe0:  0x56c03, // wbr
+	0xe2:  0x63e05, // width
+	0xe3:  0x2290c, // onafterprint
+	0xe4:  0x30505, // ismap
+	0xe5:  0x1505,  // value
+	0xe7:  0x1303,  // nav
+	0xe8:  0x54508, // ononline
+	0xe9:  0xb604,  // mark
+	0xea:  0xc303,  // low
+	0xeb:  0x3ee0b, // ondragstart
+	0xef:  0x12f03, // xmp
+	0xf0:  0x22407, // caption
+	0xf1:  0xd904,  // type
+	0xf2:  0x70907, // summary
+	0xf3:  0x6802,  // tt
+	0xf4:  0x20809, // translate
+	0xf5:  0x1870a, // blockquote
+	0xf8:  0x15702, // hr
+	0xfa:  0x2705,  // tbody
+	0xfc:  0x7b07,  // picture
+	0xfd:  0x5206,  // height
+	0xfe:  0x19c04, // cite
+	0xff:  0x2501,  // s
+	0x101: 0xff05,  // async
+	0x102: 0x56f07, // onpaste
+	0x103: 0x19507, // onabort
+	0x104: 0x2b706, // target
+	0x105: 0x14b03, // bdo
+	0x106: 0x1f006, // coords
+	0x107: 0x5e108, // onresize
+	0x108: 0x71908, // template
+	0x10a: 0x3a02,  // rb
+	0x10b: 0x2a50a, // novalidate
+	0x10c: 0x460e,  // updateviacache
+	0x10d: 0x71003, // sup
+	0x10e: 0x6c07,  // noembed
+	0x10f: 0x16b03, // div
+	0x110: 0x6f707, // srclang
+	0x111: 0x17a09, // draggable
+	0x112: 0x67305, // scope
+	0x113: 0x5905,  // label
+	0x114: 0x22f02, // rp
+	0x115: 0x23f08, // required
+	0x116: 0x3780d, // oncontextmenu
+	0x117: 0x5e504, // size
+	0x118: 0x5b00a, // spellcheck
+	0x119: 0x3f04,  // font
+	0x11a: 0x9c07,  // rowspan
+	0x11b: 0x10a07, // default
+	0x11d: 0x44307, // oninput
+	0x11e: 0x38506, // itemid
+	0x11f: 0x5ee04, // code
+	0x120: 0xaa07,  // acronym
+	0x121: 0x3b04,  // base
+	0x125: 0x2470d, // foreignObject
+	0x126: 0x2ca04, // high
+	0x127: 0x3cb0e, // referrerpolicy
+	0x128: 0x33703, // max
+	0x129: 0x59d0a, // onpopstate
+	0x12a: 0x2fc02, // h4
+	0x12b: 0x4ac04, // meta
+	0x12c: 0x17305, // blink
+	0x12e: 0x5f508, // onscroll
+	0x12f: 0x59409, // onplaying
+	0x130: 0xc113,  // allowpaymentrequest
+	0x131: 0x19a03, // rtc
+	0x132: 0x72b04, // wrap
+	0x134: 0x8b08,  // frameset
+	0x135: 0x32605, // small
+	0x137: 0x32006, // header
+	0x138: 0x40409, // onemptied
+	0x139: 0x34902, // h6
+	0x13a: 0x35908, // multiple
+	0x13c: 0x52a06, // prompt
+	0x13f: 0x28e09, // challenge
+	0x141: 0x4370c, // onhashchange
+	0x142: 0x57b07, // content
+	0x143: 0x1c90e, // annotation-xml
+	0x144: 0x36607, // onclose
+	0x145: 0x14d10, // oncanplaythrough
+	0x148: 0x5170b, // onmouseover
+	0x149: 0x64f08, // sortable
+	0x14a: 0xa402,  // mo
+	0x14b: 0x2cd02, // h3
+	0x14c: 0x2c406, // script
+	0x14d: 0x41d07, // onended
+	0x14f: 0x64706, // poster
+	0x150: 0x7210a, // workertype
+	0x153: 0x1f505, // shape
+	0x154: 0x4,     // abbr
+	0x155: 0x1,     // a
+	0x156: 0x2bf02, // dd
+	0x157: 0x71606, // system
+	0x158: 0x4ce0e, // onmessageerror
+	0x159: 0x36b08, // seamless
+	0x15a: 0x2610a, // formaction
+	0x15b: 0x6e106, // option
+	0x15c: 0x31d04, // math
+	0x15d: 0x62609, // onseeking
+	0x15e: 0x39c05, // oncut
+	0x15f: 0x44c03, // del
+	0x160: 0x11005, // title
+	0x161: 0x11505, // audio
+	0x162: 0x63108, // selected
+	0x165: 0x3b40b, // ondragenter
+	0x166: 0x46e06, // spacer
+	0x167: 0x4a410, // onloadedmetadata
+	0x168: 0x44505, // input
+	0x16a: 0x58505, // table
+	0x16b: 0x41508, // onchange
+	0x16e: 0x5f005, // defer
+	0x171: 0x50a0a, // onmouseout
+	0x172: 0x20504, // slot
+	0x175: 0x3704,  // nobr
+	0x177: 0x1d707, // command
+	0x17a: 0x7207,  // details
+	0x17b: 0x38104, // menu
+	0x17c: 0xb903,  // kbd
+	0x17d: 0x57304, // step
+	0x17e: 0x20303, // ins
+	0x17f: 0x13c08, // autoplay
+	0x182: 0x34103, // min
+	0x183: 0x17404, // link
+	0x185: 0x40d10, // ondurationchange
+	0x186: 0x9202,  // td
+	0x187: 0x8b05,  // frame
+	0x18a: 0x2ab08, // datetime
+	0x18b: 0x44509, // inputmode
+	0x18c: 0x35108, // readonly
+	0x18d: 0x21104, // face
+	0x18f: 0x5e505, // sizes
+	0x191: 0x4b208, // tabindex
+	0x192: 0x6db06, // strong
+	0x193: 0xba03,  // bdi
+	0x194: 0x6fe06, // srcset
+	0x196: 0x67202, // ms
+	0x197: 0x5b507, // checked
+	0x198: 0xb105,  // align
+	0x199: 0x1e507, // section
+	0x19b: 0x6e05,  // embed
+	0x19d: 0x15e07, // bgsound
+	0x1a2: 0x49d04, // list
+	0x1a3: 0x61e08, // onseeked
+	0x1a4: 0x66009, // onstorage
+	0x1a5: 0x2f603, // img
+	0x1a6: 0xf505,  // tfoot
+	0x1a9: 0x26913, // onautocompleteerror
+	0x1aa: 0x5fd19, // onsecuritypolicyviolation
+	0x1ad: 0x9303,  // dir
+	0x1ae: 0x9307,  // dirname
+	0x1b0: 0x5a70a, // onprogress
+	0x1b2: 0x65709, // onstalled
+	0x1b5: 0x66f09, // itemscope
+	0x1b6: 0x49904, // data
+	0x1b7: 0x3d90b, // ondragleave
+	0x1b8: 0x56102, // h2
+	0x1b9: 0x2f706, // mglyph
+	0x1ba: 0x16502, // is
+	0x1bb: 0x6e50e, // onbeforeunload
+	0x1bc: 0x2830d, // typemustmatch
+	0x1bd: 0x3ab06, // ondrag
+	0x1be: 0x5da07, // onreset
+	0x1c0: 0x51106, // output
+	0x1c1: 0x12907, // sandbox
+	0x1c2: 0x1b209, // plaintext
+	0x1c4: 0x34c08, // textarea
+	0x1c7: 0xd607,  // keytype
+	0x1c8: 0x34b05, // mtext
+	0x1c9: 0x6b10e, // onvolumechange
+	0x1ca: 0x1ea06, // onblur
+	0x1cb: 0x58a07, // onpause
+	0x1cd: 0x5bc0c, // onratechange
+	0x1ce: 0x10705, // aside
+	0x1cf: 0x6cf07, // optimum
+	0x1d1: 0x45809, // onkeydown
+	0x1d2: 0x1c407, // colspan
+	0x1d3: 0x1004,  // main
+	0x1d4: 0x66b03, // sub
+	0x1d5: 0x25b06, // object
+	0x1d6: 0x55c06, // search
+	0x1d7: 0x37206, // sorted
+	0x1d8: 0x17003, // big
+	0x1d9: 0xb01,   // u
+	0x1db: 0x26b0c, // autocomplete
+	0x1dc: 0xcc02,  // tr
+	0x1dd: 0xf303,  // alt
+	0x1df: 0x7804,  // samp
+	0x1e0: 0x5c812, // onrejectionhandled
+	0x1e1: 0x4f30c, // onmouseleave
+	0x1e2: 0x28007, // enctype
+	0x1e3: 0xa208,  // nomodule
+	0x1e5: 0x3280f, // allowfullscreen
+	0x1e6: 0x5f08,  // optgroup
+	0x1e8: 0x27c0b, // formenctype
+	0x1e9: 0x18106, // legend
+	0x1ea: 0x10306, // canvas
+	0x1eb: 0x6607,  // pattern
+	0x1ec: 0x2c208, // noscript
+	0x1ed: 0x601,   // i
+	0x1ee: 0x5d602, // dl
+	0x1ef: 0xa702,  // ul
+	0x1f2: 0x52209, // onmouseup
+	0x1f4: 0x1ba05, // track
+	0x1f7: 0x3a10a, // ondblclick
+	0x1f8: 0x3bf0a, // ondragexit
+	0x1fa: 0x8703,  // dfn
+	0x1fc: 0x26506, // action
+	0x1fd: 0x35004, // area
+	0x1fe: 0x31607, // marquee
+	0x1ff: 0x16d03, // var
 }
 
 const atomText = "abbradiogrouparamainavalueaccept-charsetbodyaccesskeygenobrb" +
@@ -758,26 +760,26 @@ const atomText = "abbradiogrouparamainavalueaccept-charsetbodyaccesskeygenobrb"
 	"dboxmplaceholderautoplaysinlinebdoncanplaythrough1bgsoundisa" +
 	"bledivarbigblinkindraggablegendblockquotebuttonabortcitempro" +
 	"penoncecolgrouplaintextrackcolorcolspannotation-xmlcommandco" +
-	"ntrolshapecoordslotranslatecrossoriginsmallowfullscreenoscri" +
-	"ptfacenterfieldsetfigcaptionafterprintegrityfigurequiredfore" +
-	"ignObjectforeignobjectformactionautocompleteerrorformenctype" +
-	"mustmatchallengeformmethodformnovalidatetimeformtargethgroup" +
-	"osterhiddenhigh2hreflanghttp-equivideonclickiframeimageimgly" +
-	"ph3isindexismappletitemtypemarqueematheadersortedmaxlength4m" +
-	"inlength5mtextareadonlymultiplemutedoncloseamlessourceoncont" +
-	"extmenuitemidoncopyoncuechangeoncutondblclickondragendondrag" +
-	"enterondragexitemreferrerpolicyondragleaveondragoverondragst" +
-	"articleondropzonemptiedondurationchangeonendedonerroronfocus" +
-	"paceronhashchangeoninputmodeloninvalidonkeydownloadonkeypres" +
-	"spellcheckedonkeyupreloadonlanguagechangeonloadeddatalisting" +
-	"onloadedmetadatabindexonloadendonloadstartonmessageerroronmo" +
-	"usedownonmouseenteronmouseleaveonmousemoveonmouseoutputonmou" +
-	"seoveronmouseupromptonmousewheelonofflineononlineonpagehides" +
-	"classectionbluronpageshowbronpastepublicontenteditableonpaus" +
-	"emaponplayingonpopstateonprogressrcdocodeferonratechangeonre" +
-	"jectionhandledonresetonresizesrclangonscrollonsecuritypolicy" +
-	"violationauxclickonseekedonseekingonselectedonshowidth6onsor" +
-	"tableonstalledonstorageonsubmitemscopedonsuspendontoggleonun" +
-	"handledrejectionbeforeprintonunloadonvolumechangeonwaitingon" +
-	"wheeloptimumanifestrongoptionbeforeunloaddressrcsetstylesumm" +
-	"arysupsvgsystemplateworkertypewrap"
+	"ntrolsectionblurcoordshapecrossoriginslotranslatefacenterfie" +
+	"ldsetfigcaptionafterprintegrityfigurequiredforeignObjectfore" +
+	"ignobjectformactionautocompleteerrorformenctypemustmatchalle" +
+	"ngeformmethodformnovalidatetimeformtargethiddenoscripthigh3h" +
+	"reflanghttp-equivideonclickiframeimageimglyph4isindexismappl" +
+	"etitemtypemarqueematheadersmallowfullscreenmaxlength5minleng" +
+	"th6mtextareadonlymultiplemutedoncloseamlessortedoncontextmen" +
+	"uitemidoncopyoncuechangeoncutondblclickondragendondragentero" +
+	"ndragexitemreferrerpolicyondragleaveondragoverondragstarticl" +
+	"eondropzonemptiedondurationchangeonendedonerroronfocusourceo" +
+	"nhashchangeoninputmodeloninvalidonkeydownloadonkeypresspacer" +
+	"onkeyupreloadonlanguagechangeonloadeddatalistingonloadedmeta" +
+	"databindexonloadendonloadstartonmessageerroronmousedownonmou" +
+	"seenteronmouseleaveonmousemoveonmouseoutputonmouseoveronmous" +
+	"eupromptonmousewheelonofflineononlineonpagehidesclassearch2o" +
+	"npageshowbronpastepublicontenteditableonpausemaponplayingonp" +
+	"opstateonprogresspellcheckedonratechangeonrejectionhandledon" +
+	"resetonresizesrcdocodeferonscrollonsecuritypolicyviolationau" +
+	"xclickonseekedonseekingonselectedonshowidthgrouposteronsorta" +
+	"bleonstalledonstorageonsubmitemscopedonsuspendontoggleonunha" +
+	"ndledrejectionbeforeprintonunloadonvolumechangeonwaitingonwh" +
+	"eeloptimumanifestrongoptionbeforeunloaddressrclangsrcsetstyl" +
+	"esummarysupsvgsystemplateworkertypewrap"
diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go
index 643c674e3..518ee4c94 100644
--- a/vendor/golang.org/x/net/html/parse.go
+++ b/vendor/golang.org/x/net/html/parse.go
@@ -924,7 +924,7 @@ func inBodyIM(p *parser) bool {
 			p.addElement()
 			p.im = inFramesetIM
 			return true
-		case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Main, a.Menu, a.Nav, a.Ol, a.P, a.Section, a.Summary, a.Ul:
+		case a.Address, a.Article, a.Aside, a.Blockquote, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Main, a.Menu, a.Nav, a.Ol, a.P, a.Search, a.Section, a.Summary, a.Ul:
 			p.popUntil(buttonScope, a.P)
 			p.addElement()
 		case a.H1, a.H2, a.H3, a.H4, a.H5, a.H6:
@@ -1136,7 +1136,7 @@ func inBodyIM(p *parser) bool {
 				return false
 			}
 			return true
-		case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Main, a.Menu, a.Nav, a.Ol, a.Pre, a.Section, a.Summary, a.Ul:
+		case a.Address, a.Article, a.Aside, a.Blockquote, a.Button, a.Center, a.Details, a.Dialog, a.Dir, a.Div, a.Dl, a.Fieldset, a.Figcaption, a.Figure, a.Footer, a.Header, a.Hgroup, a.Listing, a.Main, a.Menu, a.Nav, a.Ol, a.Pre, a.Search, a.Section, a.Summary, a.Ul:
 			p.popUntil(defaultScope, p.tok.DataAtom)
 		case a.Form:
 			if p.oe.contains(a.Template) {
diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go
index 3c57880d6..6598c1f7b 100644
--- a/vendor/golang.org/x/net/html/token.go
+++ b/vendor/golang.org/x/net/html/token.go
@@ -839,8 +839,22 @@ func (z *Tokenizer) readStartTag() TokenType {
 	if raw {
 		z.rawTag = strings.ToLower(string(z.buf[z.data.start:z.data.end]))
 	}
-	// Look for a self-closing token like "<br/>".
-	if z.err == nil && z.buf[z.raw.end-2] == '/' {
+	// Look for a self-closing token (e.g. <br/>).
+	//
+	// Originally, we did this by just checking that the last character of the
+	// tag (ignoring the closing bracket) was a solidus (/) character, but this
+	// is not always accurate.
+	//
+	// We need to be careful that we don't misinterpret a non-self-closing tag
+	// as self-closing, as can happen if the tag contains unquoted attribute
+	// values (i.e. <p a=/>).
+	//
+	// To avoid this, we check that the last non-bracket character of the tag
+	// (z.raw.end-2) isn't the same character as the last non-quote character of
+	// the last attribute of the tag (z.pendingAttr[1].end-1), if the tag has
+	// attributes.
+	nAttrs := len(z.attr)
+	if z.err == nil && z.buf[z.raw.end-2] == '/' && (nAttrs == 0 || z.raw.end-2 != z.attr[nAttrs-1][1].end-1) {
 		return SelfClosingTagToken
 	}
 	return StartTagToken
diff --git a/vendor/golang.org/x/net/http2/frame.go b/vendor/golang.org/x/net/http2/frame.go
index 81faec7e7..97bd8b06f 100644
--- a/vendor/golang.org/x/net/http2/frame.go
+++ b/vendor/golang.org/x/net/http2/frame.go
@@ -225,6 +225,11 @@ var fhBytes = sync.Pool{
 	},
 }
 
+func invalidHTTP1LookingFrameHeader() FrameHeader {
+	fh, _ := readFrameHeader(make([]byte, frameHeaderLen), strings.NewReader("HTTP/1.1 "))
+	return fh
+}
+
 // ReadFrameHeader reads 9 bytes from r and returns a FrameHeader.
 // Most users should use Framer.ReadFrame instead.
 func ReadFrameHeader(r io.Reader) (FrameHeader, error) {
@@ -503,10 +508,16 @@ func (fr *Framer) ReadFrame() (Frame, error) {
 		return nil, err
 	}
 	if fh.Length > fr.maxReadSize {
+		if fh == invalidHTTP1LookingFrameHeader() {
+			return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", err)
+		}
 		return nil, ErrFrameTooLarge
 	}
 	payload := fr.getReadBuf(fh.Length)
 	if _, err := io.ReadFull(fr.r, payload); err != nil {
+		if fh == invalidHTTP1LookingFrameHeader() {
+			return nil, fmt.Errorf("http2: failed reading the frame payload: %w, note that the frame header looked like an HTTP/1.1 header", err)
+		}
 		return nil, err
 	}
 	f, err := typeFrameParser(fh.Type)(fr.frameCache, fh, fr.countError, payload)
diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go
index b640deb0e..51fca38f6 100644
--- a/vendor/golang.org/x/net/http2/server.go
+++ b/vendor/golang.org/x/net/http2/server.go
@@ -1068,7 +1068,10 @@ func (sc *serverConn) serve(conf http2Config) {
 
 func (sc *serverConn) handlePingTimer(lastFrameReadTime time.Time) {
 	if sc.pingSent {
-		sc.vlogf("timeout waiting for PING response")
+		sc.logf("timeout waiting for PING response")
+		if f := sc.countErrorFunc; f != nil {
+			f("conn_close_lost_ping")
+		}
 		sc.conn.Close()
 		return
 	}
diff --git a/vendor/golang.org/x/net/websocket/websocket.go b/vendor/golang.org/x/net/websocket/websocket.go
index ac76165ce..3448d2039 100644
--- a/vendor/golang.org/x/net/websocket/websocket.go
+++ b/vendor/golang.org/x/net/websocket/websocket.go
@@ -6,9 +6,10 @@
 // as specified in RFC 6455.
 //
 // This package currently lacks some features found in an alternative
-// and more actively maintained WebSocket package:
+// and more actively maintained WebSocket packages:
 //
-//	https://pkg.go.dev/github.com/coder/websocket
+//   - [github.com/gorilla/websocket]
+//   - [github.com/coder/websocket]
 package websocket // import "golang.org/x/net/websocket"
 
 import (
diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go
index a4ea5d14f..f8c3c0926 100644
--- a/vendor/golang.org/x/sync/errgroup/errgroup.go
+++ b/vendor/golang.org/x/sync/errgroup/errgroup.go
@@ -18,7 +18,7 @@ import (
 type token struct{}
 
 // A Group is a collection of goroutines working on subtasks that are part of
-// the same overall task.
+// the same overall task. A Group should not be reused for different tasks.
 //
 // A zero Group is valid, has no limit on the number of active goroutines,
 // and does not cancel on error.
@@ -61,6 +61,7 @@ func (g *Group) Wait() error {
 }
 
 // Go calls the given function in a new goroutine.
+// The first call to Go must happen before a Wait.
 // It blocks until the new goroutine can be added without the number of
 // active goroutines in the group exceeding the configured limit.
 //
diff --git a/vendor/modules.txt b/vendor/modules.txt
index e63f8efb9..997ecd70c 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -466,7 +466,7 @@ golang.org/x/exp/slices
 golang.org/x/mod/internal/lazyregexp
 golang.org/x/mod/module
 golang.org/x/mod/semver
-# golang.org/x/net v0.37.0
+# golang.org/x/net v0.38.0
 ## explicit; go 1.23.0
 golang.org/x/net/context
 golang.org/x/net/html
@@ -486,7 +486,7 @@ golang.org/x/net/websocket
 ## explicit; go 1.23.0
 golang.org/x/oauth2
 golang.org/x/oauth2/internal
-# golang.org/x/sync v0.12.0
+# golang.org/x/sync v0.13.0
 ## explicit; go 1.23.0
 golang.org/x/sync/errgroup
 golang.org/x/sync/singleflight
@@ -1670,7 +1670,7 @@ sigs.k8s.io/kustomize/kyaml/yaml/internal/k8sgen/pkg/util/validation/field
 sigs.k8s.io/kustomize/kyaml/yaml/merge2
 sigs.k8s.io/kustomize/kyaml/yaml/schema
 sigs.k8s.io/kustomize/kyaml/yaml/walk
-# sigs.k8s.io/lws v0.6.0
+# sigs.k8s.io/lws v0.6.1
 ## explicit; go 1.24.0
 sigs.k8s.io/lws/api/leaderworkerset/scheme
 sigs.k8s.io/lws/api/leaderworkerset/v1



Test patch:
diff --git a/charts/kueue/tests/manager_test.yaml b/charts/kueue/tests/manager_test.yaml
new file mode 100644
index 000000000..875dcf28c
--- /dev/null
+++ b/charts/kueue/tests/manager_test.yaml
@@ -0,0 +1,15 @@
+suite: test manager deployment
+templates:
+  - manager/manager.yaml
+  # This is required for the annotation `charts.kueue.x-k8s.io/config-checksum`
+  - manager/manager-config.yaml
+tests:
+  - it: should set replicas correctly
+    template: manager/manager.yaml
+    set:
+      controllerManager:
+        replicas: 2
+    asserts:
+      - equal:
+          path: spec.replicas
+          value: 2
diff --git a/pkg/cache/cache_test.go b/pkg/cache/cache_test.go
index d79611a76..3601ac379 100644
--- a/pkg/cache/cache_test.go
+++ b/pkg/cache/cache_test.go
@@ -734,7 +734,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 					Preemption:                    defaultPreemption,
 					AllocatableResourceGeneration: 1,
 					FlavorFungibility:             defaultFlavorFungibility,
-					AdmissionChecks: map[string]sets.Set[kueue.ResourceFlavorReference]{
+					AdmissionChecks: map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference]{
 						"check1": sets.New[kueue.ResourceFlavorReference](),
 						"check2": sets.New[kueue.ResourceFlavorReference](),
 					},
@@ -766,7 +766,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 					Preemption:                    defaultPreemption,
 					AllocatableResourceGeneration: 1,
 					FlavorFungibility:             defaultFlavorFungibility,
-					AdmissionChecks: map[string]sets.Set[kueue.ResourceFlavorReference]{
+					AdmissionChecks: map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference]{
 						"check1": sets.New[kueue.ResourceFlavorReference](),
 						"check2": sets.New[kueue.ResourceFlavorReference](),
 					},
@@ -799,7 +799,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 					Preemption:                    defaultPreemption,
 					AllocatableResourceGeneration: 1,
 					FlavorFungibility:             defaultFlavorFungibility,
-					AdmissionChecks: map[string]sets.Set[kueue.ResourceFlavorReference]{
+					AdmissionChecks: map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference]{
 						"check1": sets.New[kueue.ResourceFlavorReference](),
 						"check2": sets.New[kueue.ResourceFlavorReference](),
 					},
@@ -832,7 +832,7 @@ func TestCacheClusterQueueOperations(t *testing.T) {
 					Preemption:                    defaultPreemption,
 					AllocatableResourceGeneration: 1,
 					FlavorFungibility:             defaultFlavorFungibility,
-					AdmissionChecks: map[string]sets.Set[kueue.ResourceFlavorReference]{
+					AdmissionChecks: map[kueue.AdmissionCheckReference]sets.Set[kueue.ResourceFlavorReference]{
 						"check1": sets.New[kueue.ResourceFlavorReference](),
 						"check2": sets.New[kueue.ResourceFlavorReference](),
 					},
@@ -3277,7 +3277,7 @@ func TestClusterQueuesUsingAdmissionChecks(t *testing.T) {
 	cases := map[string]struct {
 		clusterQueues              []*kueue.ClusterQueue
 		wantInUseClusterQueueNames []kueue.ClusterQueueReference
-		check                      string
+		check                      kueue.AdmissionCheckReference
 	}{
 		"single clusterQueue with check in use": {
 			clusterQueues:              []*kueue.ClusterQueue{fooCq},
@@ -3338,7 +3338,7 @@ func TestClusterQueueReadiness(t *testing.T) {
 		ResourceGroup(
 			*utiltesting.MakeFlavorQuotas(baseFlavor.Name).
 				Resource(corev1.ResourceCPU, "10", "10").Obj()).
-		AdmissionChecks(baseCheck.Name).
+		AdmissionChecks(kueue.AdmissionCheckReference(baseCheck.Name)).
 		Obj()
 
 	cases := map[string]struct {
diff --git a/pkg/cache/clusterqueue_test.go b/pkg/cache/clusterqueue_test.go
index 26ec7993f..d031330e9 100644
--- a/pkg/cache/clusterqueue_test.go
+++ b/pkg/cache/clusterqueue_test.go
@@ -188,27 +188,20 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			*utiltesting.MakeAdmissionCheckStrategyRule("check3").Obj()).
 		Obj()
 
-	cqWithACPerFlavor := utiltesting.MakeClusterQueue("cq3").
-		AdmissionCheckStrategy(
-			*utiltesting.MakeAdmissionCheckStrategyRule("check1", "flavor1", "flavor2", "flavor3").Obj(),
-		).
-		Obj()
-
 	testcases := []struct {
-		name                     string
-		cq                       *kueue.ClusterQueue
-		cqStatus                 metrics.ClusterQueueStatus
-		admissionChecks          map[string]AdmissionCheck
-		wantStatus               metrics.ClusterQueueStatus
-		wantReason               string
-		wantMessage              string
-		acValidationRulesEnabled bool
+		name            string
+		cq              *kueue.ClusterQueue
+		cqStatus        metrics.ClusterQueueStatus
+		admissionChecks map[kueue.AdmissionCheckReference]AdmissionCheck
+		wantStatus      metrics.ClusterQueueStatus
+		wantReason      string
+		wantMessage     string
 	}{
 		{
 			name:     "Pending clusterQueue updated valid AC list",
 			cq:       cqWithAC,
 			cqStatus: pending,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -226,34 +219,11 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			wantReason:  "Ready",
 			wantMessage: "Can admit new workloads",
 		},
-		{
-			name:     "Pending clusterQueue updated valid AC list - AdmissionCheckValidationRules enabled",
-			cq:       cqWithAC,
-			cqStatus: pending,
-			admissionChecks: map[string]AdmissionCheck{
-				"check1": {
-					Active:     true,
-					Controller: "controller1",
-				},
-				"check2": {
-					Active:     true,
-					Controller: "controller2",
-				},
-				"check3": {
-					Active:     true,
-					Controller: "controller3",
-				},
-			},
-			wantStatus:               active,
-			wantReason:               "Ready",
-			wantMessage:              "Can admit new workloads",
-			acValidationRulesEnabled: true,
-		},
 		{
 			name:     "Pending clusterQueue with an AC strategy updated valid AC list",
 			cq:       cqWithACStrategy,
 			cqStatus: pending,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -275,7 +245,7 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			name:     "Active clusterQueue updated with not found AC",
 			cq:       cqWithAC,
 			cqStatus: active,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -293,7 +263,7 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			name:     "Active clusterQueue with an AC strategy updated with not found AC",
 			cq:       cqWithACStrategy,
 			cqStatus: active,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -311,7 +281,7 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			name:     "Active clusterQueue updated with inactive AC",
 			cq:       cqWithAC,
 			cqStatus: active,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -333,7 +303,7 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			name:     "Active clusterQueue with an AC strategy updated with inactive AC",
 			cq:       cqWithACStrategy,
 			cqStatus: active,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -351,61 +321,11 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			wantReason:  "AdmissionCheckInactive",
 			wantMessage: "Can't admit new workloads: references inactive AdmissionCheck(s): [check3].",
 		},
-		{
-			name:     "Active clusterQueue updated with duplicate single instance AC Controller - AdmissionCheckValidationRules enabled",
-			cq:       cqWithAC,
-			cqStatus: active,
-			admissionChecks: map[string]AdmissionCheck{
-				"check1": {
-					Active:                       true,
-					Controller:                   "controller1",
-					SingleInstanceInClusterQueue: true,
-				},
-				"check2": {
-					Active:     true,
-					Controller: "controller2",
-				},
-				"check3": {
-					Active:                       true,
-					Controller:                   "controller2",
-					SingleInstanceInClusterQueue: true,
-				},
-			},
-			wantStatus:               pending,
-			wantReason:               "MultipleSingleInstanceControllerAdmissionChecks",
-			wantMessage:              `Can't admit new workloads: only one AdmissionCheck of [check2 check3] can be referenced for controller "controller2".`,
-			acValidationRulesEnabled: true,
-		},
-		{
-			name:     "Active clusterQueue with an AC strategy updated with duplicate single instance AC Controller - AdmissionCheckValidationRules enabled",
-			cq:       cqWithACStrategy,
-			cqStatus: active,
-			admissionChecks: map[string]AdmissionCheck{
-				"check1": {
-					Active:                       true,
-					Controller:                   "controller1",
-					SingleInstanceInClusterQueue: true,
-				},
-				"check2": {
-					Active:     true,
-					Controller: "controller2",
-				},
-				"check3": {
-					Active:                       true,
-					Controller:                   "controller2",
-					SingleInstanceInClusterQueue: true,
-				},
-			},
-			wantStatus:               pending,
-			wantReason:               "MultipleSingleInstanceControllerAdmissionChecks",
-			wantMessage:              `Can't admit new workloads: only one AdmissionCheck of [check2 check3] can be referenced for controller "controller2".`,
-			acValidationRulesEnabled: true,
-		},
 		{
 			name:     "Active clusterQueue with an MultiKueue AC strategy updated with duplicate single instance AC Controller",
 			cq:       cqWithACStrategy,
 			cqStatus: active,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: kueue.MultiKueueControllerName,
@@ -423,26 +343,11 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			wantReason:  kueue.ClusterQueueActiveReasonMultipleMultiKueueAdmissionChecks,
 			wantMessage: `Can't admit new workloads: Cannot use multiple MultiKueue AdmissionChecks on the same ClusterQueue, found: check1,check3.`,
 		},
-		{
-			name:     "Pending clusterQueue with a FlavorIndependent AC applied per ResourceFlavor",
-			cq:       cqWithACPerFlavor,
-			cqStatus: pending,
-			admissionChecks: map[string]AdmissionCheck{
-				"check1": {
-					Active:            true,
-					Controller:        "controller1",
-					FlavorIndependent: true,
-				},
-			},
-			wantStatus:  active,
-			wantReason:  "Ready",
-			wantMessage: "Can admit new workloads",
-		},
 		{
 			name:     "Terminating clusterQueue updated with valid AC list",
 			cq:       cqWithAC,
 			cqStatus: terminating,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -464,7 +369,7 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			name:     "Terminating clusterQueue with an AC strategy updated with valid AC list",
 			cq:       cqWithACStrategy,
 			cqStatus: terminating,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -486,7 +391,7 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			name:     "Terminating clusterQueue updated with not found AC",
 			cq:       cqWithAC,
 			cqStatus: terminating,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -504,7 +409,7 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			name:     "Terminating clusterQueue with an AC strategy updated with not found AC",
 			cq:       cqWithACStrategy,
 			cqStatus: terminating,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
 					Active:     true,
 					Controller: "controller1",
@@ -519,67 +424,31 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 			wantMessage: "Can't admit new workloads; clusterQueue is terminating",
 		},
 		{
-			name:     "Active clusterQueue with an AC strategy updated with AdmissionCheckValidationRules disabled and no MultiKueue",
+			name:     "Active clusterQueue with an AC strategy updated",
 			cq:       cqWithACStrategy,
 			cqStatus: active,
-			admissionChecks: map[string]AdmissionCheck{
+			admissionChecks: map[kueue.AdmissionCheckReference]AdmissionCheck{
 				"check1": {
-					Active:                       true,
-					Controller:                   "controller1",
-					SingleInstanceInClusterQueue: true,
+					Active:     true,
+					Controller: "controller1",
 				},
 				"check2": {
 					Active:     true,
 					Controller: "controller2",
 				},
 				"check3": {
-					Active:                       true,
-					Controller:                   "controller2",
-					SingleInstanceInClusterQueue: true,
+					Active:     true,
+					Controller: "controller2",
 				},
 			},
 			wantStatus:  active,
 			wantReason:  "Ready",
 			wantMessage: "Can admit new workloads",
 		},
-		{
-			name:     "Active clusterQueue with a FlavorIndependent AC applied per ResourceFlavor - AdmissionCheckValidationRules enabled",
-			cq:       cqWithACPerFlavor,
-			cqStatus: pending,
-			admissionChecks: map[string]AdmissionCheck{
-				"check1": {
-					Active:            true,
-					Controller:        "controller1",
-					FlavorIndependent: true,
-				},
-			},
-			wantStatus:               pending,
-			wantReason:               "FlavorIndependentAdmissionCheckAppliedPerFlavor",
-			wantMessage:              "Can't admit new workloads: AdmissionCheck(s): [check1] cannot be set at flavor level.",
-			acValidationRulesEnabled: true,
-		},
-		{
-			name:     "Active clusterQueue with a FlavorIndependent MultiKueue AC applied per ResourceFlavor",
-			cq:       cqWithACPerFlavor,
-			cqStatus: pending,
-			admissionChecks: map[string]AdmissionCheck{
-				"check1": {
-					Active:            true,
-					Controller:        kueue.MultiKueueControllerName,
-					FlavorIndependent: true,
-				},
-			},
-			wantStatus:  pending,
-			wantReason:  "MultiKueueAdmissionCheckAppliedPerFlavor",
-			wantMessage: `Can't admit new workloads: Cannot specify MultiKueue AdmissionCheck per flavor, found: check1.`,
-		},
 	}
 
 	for _, tc := range testcases {
 		t.Run(tc.name, func(t *testing.T) {
-			if tc.acValidationRulesEnabled {
-				features.SetFeatureGateDuringTest(t, features.AdmissionCheckValidationRules, true)
-			}
 			cache := New(utiltesting.NewFakeClient())
 			cq, err := cache.newClusterQueue(tc.cq)
 			if err != nil {
@@ -590,18 +459,11 @@ func TestClusterQueueUpdateWithAdmissionCheck(t *testing.T) {
 
 			// Align the admission check related internals to the desired Status.
 			if tc.cqStatus == active {
-				cq.multipleSingleInstanceControllersChecks = nil
 				cq.missingAdmissionChecks = nil
 				cq.inactiveAdmissionChecks = nil
-				cq.flavorIndependentAdmissionCheckAppliedPerFlavor = nil
 			} else {
-				cq.missingAdmissionChecks = []string{"missing-ac"}
-				cq.inactiveAdmissionChecks = []string{"inactive-ac"}
-				// can only be cleaned up when feature gate is enabled
-				if tc.acValidationRulesEnabled {
-					cq.multipleSingleInstanceControllersChecks = map[string][]string{"c1": {"ac1", "ac2"}}
-					cq.flavorIndependentAdmissionCheckAppliedPerFlavor = []string{"not-on-flavor"}
-				}
+				cq.missingAdmissionChecks = []kueue.AdmissionCheckReference{"missing-ac"}
+				cq.inactiveAdmissionChecks = []kueue.AdmissionCheckReference{"inactive-ac"}
 			}
 			cq.updateWithAdmissionChecks(tc.admissionChecks)
 
diff --git a/pkg/cache/tas_cache_test.go b/pkg/cache/tas_cache_test.go
index 4d67498d1..aa453ac01 100644
--- a/pkg/cache/tas_cache_test.go
+++ b/pkg/cache/tas_cache_test.go
@@ -295,6 +295,7 @@ func TestFindTopologyAssignment(t *testing.T) {
 		topologyRequest    *kueue.PodSetTopologyRequest
 		levels             []string
 		nodeLabels         map[string]string
+		nodeSelector       map[string]string
 		nodes              []corev1.Node
 		pods               []corev1.Pod
 		requests           resources.Requests
@@ -1944,6 +1945,116 @@ func TestFindTopologyAssignment(t *testing.T) {
 			wantReason:         `topology "default" doesn't allow to fit any of 1 pod(s)`,
 			enableFeatureGates: []featuregate.Feature{features.TASProfileMostFreeCapacity},
 		},
+		"skip node which doesn't match node selector, missing label; BestFit": {
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("x1").
+					Label("zone", "zone-a").
+					Label(corev1.LabelHostname, "x1").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:    resource.MustParse("1"),
+						corev1.ResourceMemory: resource.MustParse("1Gi"),
+						corev1.ResourcePods:   resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+			},
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(corev1.LabelHostname),
+			},
+			nodeLabels: map[string]string{
+				"zone": "zone-a",
+			},
+			levels: defaultOneLevel,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 300,
+			},
+			nodeSelector: map[string]string{
+				"custom-label-1": "custom-value-1",
+			},
+			count:      1,
+			wantReason: `topology "default" doesn't allow to fit any of 1 pod(s)`,
+		},
+		"skip node which doesn't match node selector, label exists, value doesn't match; BestFit": {
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("x1").
+					Label("zone", "zone-a").
+					Label(corev1.LabelHostname, "x1").
+					Label("custom-label-1", "value-1").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:    resource.MustParse("1"),
+						corev1.ResourceMemory: resource.MustParse("1Gi"),
+						corev1.ResourcePods:   resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+			},
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(corev1.LabelHostname),
+			},
+			nodeLabels: map[string]string{
+				"zone": "zone-a",
+			},
+			nodeSelector: map[string]string{
+				"custom-label-1": "value-2",
+			},
+			levels: defaultOneLevel,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 300,
+			},
+			count:      1,
+			wantReason: `topology "default" doesn't allow to fit any of 1 pod(s)`,
+		},
+		"allow to schedule on node which matches node; BestFit": {
+			nodes: []corev1.Node{
+				*testingnode.MakeNode("b1-r1-x1").
+					Label("zone", "zone-a").
+					Label(corev1.LabelHostname, "x1").
+					Label("custom-label-1", "value-1").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:    resource.MustParse("1"),
+						corev1.ResourceMemory: resource.MustParse("1Gi"),
+						corev1.ResourcePods:   resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+				*testingnode.MakeNode("b1-r1-x2").
+					Label("zone", "zone-a").
+					Label(corev1.LabelHostname, "x2").
+					Label("custom-label-1", "value-2").
+					StatusAllocatable(corev1.ResourceList{
+						corev1.ResourceCPU:    resource.MustParse("1"),
+						corev1.ResourceMemory: resource.MustParse("1Gi"),
+						corev1.ResourcePods:   resource.MustParse("10"),
+					}).
+					Ready().
+					Obj(),
+			},
+			topologyRequest: &kueue.PodSetTopologyRequest{
+				Required: ptr.To(corev1.LabelHostname),
+			},
+			nodeLabels: map[string]string{
+				"zone": "zone-a",
+			},
+			nodeSelector: map[string]string{
+				"custom-label-1": "value-2",
+			},
+			levels: defaultOneLevel,
+			requests: resources.Requests{
+				corev1.ResourceCPU: 1000,
+			},
+			count: 1,
+			wantAssignment: &kueue.TopologyAssignment{
+				Levels: defaultOneLevel,
+				Domains: []kueue.TopologyDomainAssignment{
+					{
+						Count: 1,
+						Values: []string{
+							"x2",
+						},
+					},
+				},
+			},
+		},
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
@@ -1978,7 +2089,8 @@ func TestFindTopologyAssignment(t *testing.T) {
 					TopologyRequest: tc.topologyRequest,
 					Template: corev1.PodTemplateSpec{
 						Spec: corev1.PodSpec{
-							Tolerations: tc.tolerations,
+							Tolerations:  tc.tolerations,
+							NodeSelector: tc.nodeSelector,
 						},
 					},
 				},
diff --git a/pkg/controller/admissionchecks/multikueue/admissioncheck_test.go b/pkg/controller/admissionchecks/multikueue/admissioncheck_test.go
index 2d776a371..4727f77c0 100644
--- a/pkg/controller/admissionchecks/multikueue/admissioncheck_test.go
+++ b/pkg/controller/admissionchecks/multikueue/admissioncheck_test.go
@@ -26,7 +26,6 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/reconcile"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
-	"sigs.k8s.io/kueue/pkg/features"
 	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 )
 
@@ -37,9 +36,8 @@ func TestReconcile(t *testing.T) {
 		reconcileFor string
 		configs      []kueue.MultiKueueConfig
 
-		wantChecks               []kueue.AdmissionCheck
-		wantError                error
-		acValidationRulesEnabled bool
+		wantChecks []kueue.AdmissionCheck
+		wantError  error
 	}{
 		"missing admissioncheck": {
 			reconcileFor: "missing-ac",
@@ -226,8 +224,6 @@ func TestReconcile(t *testing.T) {
 				*utiltesting.MakeAdmissionCheck("ac1").
 					ControllerName(kueue.MultiKueueControllerName).
 					Parameters(kueue.GroupVersion.Group, "MultiKueueConfig", "config1").
-					SingleInstanceInClusterQueue(true, SingleInstanceReason, SingleInstanceMessage, 1).
-					ApplyToAllFlavors(true, FlavorIndependentCheckReason, FlavorIndependentCheckMessage, 1).
 					Condition(metav1.Condition{
 						Type:               kueue.AdmissionCheckActive,
 						Status:             metav1.ConditionTrue,
@@ -237,49 +233,11 @@ func TestReconcile(t *testing.T) {
 					}).
 					Obj(),
 			},
-			acValidationRulesEnabled: true,
-		},
-		"extra status conditions of SingleInstance and FlavorIndependent when AdmissionCheckValidationRules is enabled": {
-			reconcileFor: "ac1",
-			checks: []kueue.AdmissionCheck{
-				*utiltesting.MakeAdmissionCheck("ac1").
-					ControllerName(kueue.MultiKueueControllerName).
-					Parameters(kueue.GroupVersion.Group, "MultiKueueConfig", "config1").
-					Generation(1).
-					Obj(),
-			},
-			configs: []kueue.MultiKueueConfig{
-				*utiltesting.MakeMultiKueueConfig("config1").Clusters("worker1").Obj(),
-			},
-			clusters: []kueue.MultiKueueCluster{
-				*utiltesting.MakeMultiKueueCluster("worker1").
-					Active(metav1.ConditionTrue, "ByTest", "by test", 1).
-					Obj(),
-			},
-			wantChecks: []kueue.AdmissionCheck{
-				*utiltesting.MakeAdmissionCheck("ac1").
-					ControllerName(kueue.MultiKueueControllerName).
-					Parameters(kueue.GroupVersion.Group, "MultiKueueConfig", "config1").
-					SingleInstanceInClusterQueue(true, SingleInstanceReason, SingleInstanceMessage, 1).
-					ApplyToAllFlavors(true, FlavorIndependentCheckReason, FlavorIndependentCheckMessage, 1).
-					Condition(metav1.Condition{
-						Type:               kueue.AdmissionCheckActive,
-						Status:             metav1.ConditionTrue,
-						Reason:             "Active",
-						Message:            `The admission check is active`,
-						ObservedGeneration: 1,
-					}).
-					Obj(),
-			},
-			acValidationRulesEnabled: true,
 		},
 	}
 
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
-			if tc.acValidationRulesEnabled {
-				features.SetFeatureGateDuringTest(t, features.AdmissionCheckValidationRules, true)
-			}
 			builder := getClientBuilder(t.Context())
 
 			builder = builder.WithLists(
diff --git a/pkg/controller/admissionchecks/provisioning/controller_test.go b/pkg/controller/admissionchecks/provisioning/controller_test.go
index 4cfa77155..3af8181de 100644
--- a/pkg/controller/admissionchecks/provisioning/controller_test.go
+++ b/pkg/controller/admissionchecks/provisioning/controller_test.go
@@ -333,10 +333,10 @@ func TestReconcile(t *testing.T) {
 			checks:  []kueue.AdmissionCheck{*baseCheck.DeepCopy()},
 			configs: []kueue.ProvisioningRequestConfig{*utiltesting.MakeProvisioningRequestConfig("config1").Obj()},
 			wantRequests: map[string]*autoscaling.ProvisioningRequest{
-				ProvisioningRequestName("wl", baseCheck.Name, 1): {
+				ProvisioningRequestName("wl", kueue.AdmissionCheckReference(baseCheck.Name), 1): {
 					ObjectMeta: metav1.ObjectMeta{
 						Namespace: TestNamespace,
-						Name:      ProvisioningRequestName("wl", baseCheck.Name, 1),
+						Name:      ProvisioningRequestName("wl", kueue.AdmissionCheckReference(baseCheck.Name), 1),
 						Labels: map[string]string{
 							constants.ManagedByKueueLabelKey: constants.ManagedByKueueLabelValue,
 						},
@@ -516,36 +516,6 @@ func TestReconcile(t *testing.T) {
 			templates:            []corev1.PodTemplate{*baseTemplate1.DeepCopy(), *baseTemplate2.DeepCopy()},
 			wantRequestsNotFound: []string{"wl-check1"},
 		},
-		"KeepQuotaForProvReqRetry; when request fails and is retried": {
-			workload: baseWorkload.DeepCopy(),
-			checks:   []kueue.AdmissionCheck{*baseCheck.DeepCopy()},
-			flavors:  []kueue.ResourceFlavor{*baseFlavor1.DeepCopy(), *baseFlavor2.DeepCopy()},
-			configs:  []kueue.ProvisioningRequestConfig{*baseConfigWithRetryStrategy.Clone().RetryLimit(2).BaseBackoff(0).Obj()},
-			requests: []autoscaling.ProvisioningRequest{
-				*requestWithCondition(baseRequest, autoscaling.Failed, metav1.ConditionTrue),
-			},
-			enableGates: []featuregate.Feature{features.KeepQuotaForProvReqRetry},
-			templates:   []corev1.PodTemplate{*baseTemplate1.DeepCopy(), *baseTemplate2.DeepCopy()},
-			wantWorkloads: map[string]*kueue.Workload{
-				baseWorkload.GetName(): (&utiltesting.WorkloadWrapper{Workload: *baseWorkload.DeepCopy()}).
-					AdmissionChecks(kueue.AdmissionCheckState{
-						Name:    "check1",
-						State:   kueue.CheckStatePending,
-						Message: "Retrying after failure: ",
-					}, kueue.AdmissionCheckState{
-						Name:  "not-provisioning",
-						State: kueue.CheckStatePending,
-					}).
-					Obj(),
-			},
-			wantEvents: []utiltesting.EventRecord{
-				{
-					Key:       client.ObjectKeyFromObject(baseWorkload),
-					EventType: corev1.EventTypeNormal,
-					Reason:    "ProvisioningRequestCreated",
-					Message:   `Created ProvisioningRequest: "wl-check1-2"`,
-				},
-			}},
 		"when request fails and is retried": {
 			workload: baseWorkload.DeepCopy(),
 			checks:   []kueue.AdmissionCheck{*baseCheck.DeepCopy()},
@@ -971,92 +941,6 @@ func TestReconcile(t *testing.T) {
 					Obj(),
 			},
 		},
-		"KeepQuotaForProvReqRetry; workload retries the admission check when is not admitted and receives the provisioning request's BookingExpired condition": {
-			workload: (&utiltesting.WorkloadWrapper{Workload: *baseWorkload.DeepCopy()}).
-				Admitted(false).
-				Obj(),
-			checks:      []kueue.AdmissionCheck{*baseCheck.DeepCopy()},
-			flavors:     []kueue.ResourceFlavor{*baseFlavor1.DeepCopy(), *baseFlavor2.DeepCopy()},
-			configs:     []kueue.ProvisioningRequestConfig{*baseConfigWithRetryStrategy.Clone().RetryLimit(1).BaseBackoff(0).Obj()},
-			enableGates: []featuregate.Feature{features.KeepQuotaForProvReqRetry},
-			requests: []autoscaling.ProvisioningRequest{
-				*requestWithConditions(baseRequest,
-					[]metav1.Condition{
-						{
-							Type:   autoscaling.Failed,
-							Status: metav1.ConditionFalse,
-						},
-						{
-							Type:   autoscaling.Provisioned,
-							Status: metav1.ConditionTrue,
-						},
-						{
-							Type:   autoscaling.Accepted,
-							Status: metav1.ConditionTrue,
-						},
-						{
-							Type:   autoscaling.BookingExpired,
-							Status: metav1.ConditionTrue,
-						},
-					}),
-			},
-			wantWorkloads: map[string]*kueue.Workload{
-				baseWorkload.GetName(): (&utiltesting.WorkloadWrapper{Workload: *baseWorkload.DeepCopy()}).
-					AdmissionChecks(kueue.AdmissionCheckState{
-						Name:    "check1",
-						State:   kueue.CheckStatePending,
-						Message: "Retrying after booking expired: ",
-					}, kueue.AdmissionCheckState{
-						Name:  "not-provisioning",
-						State: kueue.CheckStatePending,
-					}).
-					Admitted(false).
-					Obj(),
-			},
-			wantRequests: map[string]*autoscaling.ProvisioningRequest{
-				ProvisioningRequestName("wl", baseCheck.Name, 2): {
-					ObjectMeta: metav1.ObjectMeta{
-						Namespace: TestNamespace,
-						Name:      "wl-check1-2",
-						Labels: map[string]string{
-							constants.ManagedByKueueLabelKey: constants.ManagedByKueueLabelValue,
-						},
-						OwnerReferences: []metav1.OwnerReference{
-							{
-								Name: "wl",
-							},
-						},
-					},
-					Spec: autoscaling.ProvisioningRequestSpec{
-						PodSets: []autoscaling.PodSet{
-							{
-								PodTemplateRef: autoscaling.Reference{
-									Name: "ppt-wl-check1-2-ps1",
-								},
-								Count: 4,
-							},
-							{
-								PodTemplateRef: autoscaling.Reference{
-									Name: "ppt-wl-check1-2-ps2",
-								},
-								Count: 3,
-							},
-						},
-						ProvisioningClassName: "class1",
-						Parameters: map[string]autoscaling.Parameter{
-							"p1": "v1",
-						},
-					},
-				},
-			},
-			wantEvents: []utiltesting.EventRecord{
-				{
-					Key:       types.NamespacedName{Namespace: "ns", Name: "wl"},
-					EventType: corev1.EventTypeNormal,
-					Reason:    "ProvisioningRequestCreated",
-					Message:   `Created ProvisioningRequest: "wl-check1-2"`,
-				},
-			}},
 		"workload retries the admission check when is not admitted and receives the provisioning request's BookingExpired condition": {
 			workload: (&utiltesting.WorkloadWrapper{Workload: *baseWorkload.DeepCopy()}).
 				Admitted(false).
@@ -1410,7 +1294,7 @@ func TestActiveOrLastPRForChecks(t *testing.T) {
 
 	cases := map[string]struct {
 		requests   []autoscaling.ProvisioningRequest
-		wantResult map[string]*autoscaling.ProvisioningRequest
+		wantResult map[kueue.AdmissionCheckReference]*autoscaling.ProvisioningRequest
 	}{
 		"no provisioning requests": {},
 		"two provisioning requests; 1 then 2": {
@@ -1418,7 +1302,7 @@ func TestActiveOrLastPRForChecks(t *testing.T) {
 				*pr1Failed.DeepCopy(),
 				*pr2Created.DeepCopy(),
 			},
-			wantResult: map[string]*autoscaling.ProvisioningRequest{
+			wantResult: map[kueue.AdmissionCheckReference]*autoscaling.ProvisioningRequest{
 				"check": pr2Created.DeepCopy(),
 			},
 		},
@@ -1427,7 +1311,7 @@ func TestActiveOrLastPRForChecks(t *testing.T) {
 				*pr2Created.DeepCopy(),
 				*pr1Failed.DeepCopy(),
 			},
-			wantResult: map[string]*autoscaling.ProvisioningRequest{
+			wantResult: map[kueue.AdmissionCheckReference]*autoscaling.ProvisioningRequest{
 				"check": pr2Created.DeepCopy(),
 			},
 		},
@@ -1437,8 +1321,8 @@ func TestActiveOrLastPRForChecks(t *testing.T) {
 		t.Run(name, func(t *testing.T) {
 			workload := baseWorkload.DeepCopy()
 			checks := []kueue.AdmissionCheck{*baseCheck.DeepCopy()}
-			checkConfig := map[string]*kueue.ProvisioningRequestConfig{
-				baseCheck.Name: baseConfig.DeepCopy(),
+			checkConfig := map[kueue.AdmissionCheckReference]*kueue.ProvisioningRequestConfig{
+				kueue.AdmissionCheckReference(baseCheck.Name): baseConfig.DeepCopy(),
 			}
 
 			builder, ctx := getClientBuilder(t.Context())
diff --git a/pkg/controller/core/workload_controller_test.go b/pkg/controller/core/workload_controller_test.go
index 63b9dd8b9..5e5bec724 100644
--- a/pkg/controller/core/workload_controller_test.go
+++ b/pkg/controller/core/workload_controller_test.go
@@ -267,14 +267,14 @@ func TestSyncCheckStates(t *testing.T) {
 	fakeClock := testingclock.NewFakeClock(now)
 	cases := map[string]struct {
 		states               []kueue.AdmissionCheckState
-		list                 []string
+		list                 []kueue.AdmissionCheckReference
 		wantStates           []kueue.AdmissionCheckState
 		wantChange           bool
 		ignoreTransitionTime bool
 	}{
 		"nil conditions, nil list": {},
 		"add to nil conditions": {
-			list:       []string{"ac1", "ac2"},
+			list:       []kueue.AdmissionCheckReference{"ac1", "ac2"},
 			wantChange: true,
 			wantStates: []kueue.AdmissionCheckState{
 				{
@@ -299,7 +299,7 @@ func TestSyncCheckStates(t *testing.T) {
 					State: kueue.CheckStatePending,
 				},
 			},
-			list:       []string{"ac1", "ac2"},
+			list:       []kueue.AdmissionCheckReference{"ac1", "ac2"},
 			wantChange: true,
 			wantStates: []kueue.AdmissionCheckState{
 				{
@@ -339,7 +339,7 @@ func TestSyncCheckStates(t *testing.T) {
 					State: kueue.CheckStatePending,
 				},
 			},
-			list:       []string{"ac0", "ac1"},
+			list:       []kueue.AdmissionCheckReference{"ac0", "ac1"},
 			wantChange: false,
 			wantStates: []kueue.AdmissionCheckState{
 				{
diff --git a/pkg/controller/jobframework/integrationmanager_test.go b/pkg/controller/jobframework/integrationmanager_test.go
index b2c106008..dcfc8be2a 100644
--- a/pkg/controller/jobframework/integrationmanager_test.go
+++ b/pkg/controller/jobframework/integrationmanager_test.go
@@ -365,23 +365,23 @@ func TestGetJobTypeForOwner(t *testing.T) {
 	}
 	manageK1 := func() IntegrationCallbacks {
 		ret := dontManage
-		ret.IsManagingObjectsOwner = func(owner *metav1.OwnerReference) bool { return owner.Kind == "K1" }
-		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K1"}}
+		ret.GVK = schema.GroupVersionKind{Group: "test-group", Version: "v1", Kind: "K1"}
+		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K1", APIVersion: "test-group/v1"}}
 		return ret
 	}()
 	manageK2 := func() IntegrationCallbacks {
 		ret := dontManage
-		ret.IsManagingObjectsOwner = func(owner *metav1.OwnerReference) bool { return owner.Kind == "K2" }
-		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K2"}}
+		ret.GVK = schema.GroupVersionKind{Group: "test-group", Version: "v1", Kind: "K2"}
+		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K2", APIVersion: "test-group/v1"}}
 		return ret
 	}()
 	externalK3 := func() runtime.Object {
-		return &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K3"}}
+		return &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K3", APIVersion: "test-group/v1"}}
 	}()
 	disabledK4 := func() IntegrationCallbacks {
 		ret := dontManage
-		ret.IsManagingObjectsOwner = func(owner *metav1.OwnerReference) bool { return owner.Kind == "K4" }
-		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K4"}}
+		ret.GVK = schema.GroupVersionKind{Group: "test-group", Version: "v1", Kind: "K4"}
+		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K4", APIVersion: "test-group/v1"}}
 		return ret
 	}()
 
@@ -406,23 +406,23 @@ func TestGetJobTypeForOwner(t *testing.T) {
 		wantJobType runtime.Object
 	}{
 		"K1": {
-			owner:       &metav1.OwnerReference{Kind: "K1"},
+			owner:       &metav1.OwnerReference{Kind: "K1", APIVersion: "test-group/v1"},
 			wantJobType: manageK1.JobType,
 		},
 		"K2": {
-			owner:       &metav1.OwnerReference{Kind: "K2"},
+			owner:       &metav1.OwnerReference{Kind: "K2", APIVersion: "test-group/v1"},
 			wantJobType: manageK2.JobType,
 		},
 		"K3": {
-			owner:       &metav1.OwnerReference{Kind: "K3"},
+			owner:       &metav1.OwnerReference{Kind: "K3", APIVersion: "test-group/v1"},
 			wantJobType: externalK3,
 		},
 		"K4": {
-			owner:       &metav1.OwnerReference{Kind: "K4"},
+			owner:       &metav1.OwnerReference{Kind: "K4", APIVersion: "test-group/v1"},
 			wantJobType: nil,
 		},
 		"K5": {
-			owner:       &metav1.OwnerReference{Kind: "K5"},
+			owner:       &metav1.OwnerReference{Kind: "K5", APIVersion: "test-group/v1"},
 			wantJobType: nil,
 		},
 	}
@@ -509,38 +509,29 @@ func TestOwnerFrameworkEnabledChecks(t *testing.T) {
 	}
 	manageK1 := func() IntegrationCallbacks {
 		ret := dontManage
-		ret.IsManagingObjectsOwner = func(owner *metav1.OwnerReference) bool { return owner.Kind == "K1" }
-		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K1"}}
-		ret.GVK = ret.JobType.GetObjectKind().GroupVersionKind()
+		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K1", APIVersion: "test-group/v1"}}
+		ret.GVK = schema.GroupVersionKind{Group: "test-group", Version: "v1", Kind: "K1"}
 		return ret
 	}()
-	manageK2 := func() IntegrationCallbacks {
-		ret := dontManage
-		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K2"}}
-		ret.GVK = ret.JobType.GetObjectKind().GroupVersionKind()
-		return ret
-	}()
-	externalK3 := func() runtime.Object {
-		return &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K3"}}
+	externalK2 := func() runtime.Object {
+		return &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K2", APIVersion: "test-group/v1"}}
 	}()
-	disabledK4 := func() IntegrationCallbacks {
+	disabledK3 := func() IntegrationCallbacks {
 		ret := dontManage
-		ret.IsManagingObjectsOwner = func(owner *metav1.OwnerReference) bool { return owner.Kind == "K4" }
-		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K4"}}
-		ret.GVK = ret.JobType.GetObjectKind().GroupVersionKind()
+		ret.JobType = &metav1.PartialObjectMetadata{TypeMeta: metav1.TypeMeta{Kind: "K3", APIVersion: "test-group/v1"}}
+		ret.GVK = schema.GroupVersionKind{Group: "test-group", Version: "v1", Kind: "K3"}
 		return ret
 	}()
 
 	mgr := integrationManager{
-		names: []string{"manageK1", "dontManage", "manageK2", "disabledK4"},
+		names: []string{"dontManage", "manageK1", "disabledK3"},
 		integrations: map[string]IntegrationCallbacks{
 			"dontManage": dontManage,
 			"manageK1":   manageK1,
-			"manageK2":   manageK2,
-			"disabledK4": disabledK4,
+			"disabledK3": disabledK3,
 		},
 		externalIntegrations: map[string]runtime.Object{
-			"externalK3": externalK3,
+			"externalK2": externalK2,
 		},
 	}
 	mgr.enableIntegration("manageK1")
@@ -552,27 +543,22 @@ func TestOwnerFrameworkEnabledChecks(t *testing.T) {
 		wantOwnerIsEnabled bool
 	}{
 		"K1": {
-			owner:              &metav1.OwnerReference{Kind: "K1"},
+			owner:              &metav1.OwnerReference{Kind: "K1", APIVersion: "test-group/v1"},
 			wantOwnerIsManaged: true,
 			wantOwnerIsEnabled: true,
 		},
 		"K2": {
-			owner:              &metav1.OwnerReference{Kind: "K2"},
-			wantOwnerIsManaged: false,
-			wantOwnerIsEnabled: true,
-		},
-		"K3": {
-			owner:              &metav1.OwnerReference{Kind: "K3"},
+			owner:              &metav1.OwnerReference{Kind: "K2", APIVersion: "test-group/v1"},
 			wantOwnerIsManaged: true,
 			wantOwnerIsEnabled: true,
 		},
-		"K4": {
-			owner:              &metav1.OwnerReference{Kind: "K4"},
+		"K3": {
+			owner:              &metav1.OwnerReference{Kind: "K3", APIVersion: "test-group/v1"},
 			wantOwnerIsManaged: false,
 			wantOwnerIsEnabled: false,
 		},
 		"K5": {
-			owner:              &metav1.OwnerReference{Kind: "K5"},
+			owner:              &metav1.OwnerReference{Kind: "K5", APIVersion: "test-group/v1"},
 			wantOwnerIsManaged: false,
 			wantOwnerIsEnabled: false,
 		},
diff --git a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
index 05a5dc358..2a0e64700 100644
--- a/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
+++ b/pkg/controller/jobs/leaderworkerset/leaderworkerset_reconciler_test.go
@@ -71,6 +71,7 @@ func TestReconciler(t *testing.T) {
 			wantLeaderWorkerSet: leaderworkerset.MakeLeaderWorkerSet(testLWS, testNS).UID(testUID).Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
 					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(
@@ -128,6 +129,7 @@ func TestReconciler(t *testing.T) {
 				Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
 					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(
@@ -200,6 +202,7 @@ func TestReconciler(t *testing.T) {
 				Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
 					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(
@@ -231,6 +234,7 @@ func TestReconciler(t *testing.T) {
 					Priority(0).
 					Obj(),
 				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "1"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
 					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(
@@ -345,6 +349,7 @@ func TestReconciler(t *testing.T) {
 				Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
 					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(
@@ -454,6 +459,7 @@ func TestReconciler(t *testing.T) {
 				Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
 					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(
@@ -511,6 +517,7 @@ func TestReconciler(t *testing.T) {
 				Obj(),
 			wantWorkloads: []kueue.Workload{
 				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
 					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
 					Finalizers(kueue.ResourceInUseFinalizerName).
 					PodSets(
@@ -545,6 +552,89 @@ func TestReconciler(t *testing.T) {
 			},
 			enableTopologyAwareScheduling: false,
 		},
+		"should delete LeaderWorkerSet ownerReference from the redundant prebuilt workload": {
+			leaderWorkerSet:     leaderworkerset.MakeLeaderWorkerSet(testLWS, testNS).UID(testUID).Obj(),
+			wantLeaderWorkerSet: leaderworkerset.MakeLeaderWorkerSet(testLWS, testNS).UID(testUID).Obj(),
+			workloads: []kueue.Workload{
+				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
+					OwnerReference(corev1.SchemeGroupVersion.WithKind("Pod"), "test-pod1", "test-pod1-uid").
+					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
+					Finalizers(kueue.ResourceInUseFinalizerName).
+					PodSets(
+						kueue.PodSet{
+							Name: kueue.DefaultPodSetName,
+							Template: corev1.PodTemplateSpec{
+								Spec: corev1.PodSpec{
+									Containers: []corev1.Container{
+										{Name: "c", Image: "pause"},
+									},
+								},
+							},
+							Count: 1,
+						}).
+					Priority(0).
+					Obj(),
+				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "1"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
+					OwnerReference(corev1.SchemeGroupVersion.WithKind("Pod"), "test-pod2", "test-pod2-uid").
+					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
+					Finalizers(kueue.ResourceInUseFinalizerName).
+					PodSets(
+						kueue.PodSet{
+							Name: kueue.DefaultPodSetName,
+							Template: corev1.PodTemplateSpec{
+								Spec: corev1.PodSpec{
+									Containers: []corev1.Container{
+										{Name: "c", Image: "pause"},
+									},
+								},
+							},
+							Count: 1,
+						}).
+					Priority(0).
+					Obj(),
+			},
+			wantWorkloads: []kueue.Workload{
+				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "0"), testNS).
+					OwnerReference(gvk, testLWS, testUID).
+					OwnerReference(corev1.SchemeGroupVersion.WithKind("Pod"), "test-pod1", "test-pod1-uid").
+					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
+					Finalizers(kueue.ResourceInUseFinalizerName).
+					PodSets(
+						kueue.PodSet{
+							Name: kueue.DefaultPodSetName,
+							Template: corev1.PodTemplateSpec{
+								Spec: corev1.PodSpec{
+									Containers: []corev1.Container{
+										{Name: "c", Image: "pause"},
+									},
+								},
+							},
+							Count: 1,
+						}).
+					Priority(0).
+					Obj(),
+				*utiltesting.MakeWorkload(GetWorkloadName(types.UID(testUID), testLWS, "1"), testNS).
+					OwnerReference(corev1.SchemeGroupVersion.WithKind("Pod"), "test-pod2", "test-pod2-uid").
+					Annotation(podconstants.IsGroupWorkloadAnnotationKey, podconstants.IsGroupWorkloadAnnotationValue).
+					Finalizers(kueue.ResourceInUseFinalizerName).
+					PodSets(
+						kueue.PodSet{
+							Name: kueue.DefaultPodSetName,
+							Template: corev1.PodTemplateSpec{
+								Spec: corev1.PodSpec{
+									Containers: []corev1.Container{
+										{Name: "c", Image: "pause"},
+									},
+								},
+							},
+							Count: 1,
+						}).
+					Priority(0).
+					Obj(),
+			},
+		},
 	}
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
diff --git a/pkg/scheduler/flavorassigner/flavorassigner_test.go b/pkg/scheduler/flavorassigner/flavorassigner_test.go
index fc333b18f..638cf3242 100644
--- a/pkg/scheduler/flavorassigner/flavorassigner_test.go
+++ b/pkg/scheduler/flavorassigner/flavorassigner_test.go
@@ -26,6 +26,7 @@ import (
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/api/resource"
 
+	kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/cache"
 	"sigs.k8s.io/kueue/pkg/features"
@@ -410,7 +411,7 @@ func TestAssignFlavors(t *testing.T) {
 					},
 					Count: 1,
 				}},
-				Borrowing: true,
+				Borrowing: 1,
 				Usage: workload.Usage{Quota: resources.FlavorResourceQuantities{
 					{Flavor: "two", Resource: corev1.ResourceCPU}:    3_000,
 					{Flavor: "two", Resource: corev1.ResourceMemory}: 10 * utiltesting.Mi,
@@ -805,7 +806,7 @@ func TestAssignFlavors(t *testing.T) {
 						Count: 1,
 					},
 				},
-				Borrowing: true,
+				Borrowing: 1,
 				Usage: workload.Usage{Quota: resources.FlavorResourceQuantities{
 					{Flavor: "default", Resource: corev1.ResourceCPU}:    10_000,
 					{Flavor: "default", Resource: corev1.ResourceMemory}: 5 * utiltesting.Gi,
@@ -892,7 +893,7 @@ func TestAssignFlavors(t *testing.T) {
 					},
 					Count: 1,
 				}},
-				Borrowing: true,
+				Borrowing: 1,
 				Usage: workload.Usage{Quota: resources.FlavorResourceQuantities{
 					{Flavor: "one", Resource: corev1.ResourceCPU}: 2_000,
 				}},
@@ -974,7 +975,7 @@ func TestAssignFlavors(t *testing.T) {
 					},
 					Count: 1,
 				}},
-				Borrowing: true,
+				Borrowing: 1,
 				Usage: workload.Usage{Quota: resources.FlavorResourceQuantities{
 					{Flavor: "one", Resource: corev1.ResourceCPU}: 2_000,
 				}},
@@ -1340,7 +1341,7 @@ func TestAssignFlavors(t *testing.T) {
 				Obj(),
 			wantRepMode: Fit,
 			wantAssignment: Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 				PodSets: []PodSetAssignment{{
 					Name: kueue.DefaultPodSetName,
 					Flavors: ResourceAssignment{
@@ -1441,7 +1442,7 @@ func TestAssignFlavors(t *testing.T) {
 				Obj(),
 			wantRepMode: Fit,
 			wantAssignment: Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 				PodSets: []PodSetAssignment{{
 					Name: kueue.DefaultPodSetName,
 					Flavors: ResourceAssignment{
@@ -1498,7 +1499,7 @@ func TestAssignFlavors(t *testing.T) {
 			},
 			wantRepMode: Preempt,
 			wantAssignment: Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 				PodSets: []PodSetAssignment{{
 					Name: kueue.DefaultPodSetName,
 					Flavors: ResourceAssignment{
@@ -1555,7 +1556,7 @@ func TestAssignFlavors(t *testing.T) {
 			},
 			wantRepMode: Preempt,
 			wantAssignment: Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 				PodSets: []PodSetAssignment{{
 					Name: kueue.DefaultPodSetName,
 					Flavors: ResourceAssignment{
@@ -1768,7 +1769,7 @@ func TestAssignFlavors(t *testing.T) {
 					},
 					Count: 1,
 				}},
-				Borrowing: true,
+				Borrowing: 1,
 				Usage: workload.Usage{Quota: resources.FlavorResourceQuantities{
 					{Flavor: "one", Resource: corev1.ResourceCPU}:  9_000,
 					{Flavor: "one", Resource: corev1.ResourcePods}: 1,
@@ -1818,7 +1819,7 @@ func TestAssignFlavors(t *testing.T) {
 					},
 					Count: 1,
 				}},
-				Borrowing: true,
+				Borrowing: 1,
 				Usage: workload.Usage{Quota: resources.FlavorResourceQuantities{
 					{Flavor: "one", Resource: corev1.ResourceCPU}:  9_000,
 					{Flavor: "one", Resource: corev1.ResourcePods}: 1,
@@ -1856,7 +1857,7 @@ func TestAssignFlavors(t *testing.T) {
 			},
 			wantRepMode: Preempt,
 			wantAssignment: Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 				PodSets: []PodSetAssignment{{
 					Name: kueue.DefaultPodSetName,
 					Flavors: ResourceAssignment{
@@ -2322,3 +2323,135 @@ func TestLastAssignmentOutdated(t *testing.T) {
 		})
 	}
 }
+
+// We have 3 flavors: one, two, three and a 3-level cohort hierarchy where
+// each cohort get 4 units of CPU in a different flavor.
+func TestHierarchical(t *testing.T) {
+	type rfMap = map[corev1.ResourceName]kueue.ResourceFlavorReference
+	cases := map[string]struct {
+		workloadRequests       *utiltesting.PodSetWrapper
+		testClusterQueueUsage  resources.FlavorResourceQuantities
+		otherClusterQueueUsage resources.FlavorResourceQuantities
+		flavorFungibility      *kueue.FlavorFungibility
+		wantMode               FlavorAssignmentMode
+		wantAssigment          rfMap
+	}{
+		"Select the top flavor": {
+			workloadRequests: utiltesting.MakePodSet(kueue.DefaultPodSetName, 1).Request(corev1.ResourceCPU, "4"),
+			testClusterQueueUsage: resources.FlavorResourceQuantities{
+				{Flavor: "one", Resource: corev1.ResourceCPU}: 4_000,
+			},
+			otherClusterQueueUsage: resources.FlavorResourceQuantities{
+				{Flavor: "two", Resource: corev1.ResourceCPU}: 4_000,
+			},
+			wantMode:      Fit,
+			wantAssigment: rfMap{corev1.ResourceCPU: "three"},
+		},
+		"Select the first flavor which fits": {
+			workloadRequests: utiltesting.MakePodSet(kueue.DefaultPodSetName, 1).Request(corev1.ResourceCPU, "4"),
+			testClusterQueueUsage: resources.FlavorResourceQuantities{
+				{Flavor: "one", Resource: corev1.ResourceCPU}: 4_000,
+			},
+			wantMode:      Fit,
+			wantAssigment: rfMap{corev1.ResourceCPU: "two"},
+		},
+	}
+	for name, tc := range cases {
+		t.Run(name, func(t *testing.T) {
+			ctx, _ := utiltesting.ContextWithLog(t)
+			resourceFlavors := map[kueue.ResourceFlavorReference]*kueue.ResourceFlavor{
+				"one":   utiltesting.MakeResourceFlavor("one").Obj(),
+				"two":   utiltesting.MakeResourceFlavor("two").Obj(),
+				"three": utiltesting.MakeResourceFlavor("three").Obj(),
+			}
+			cohorts := []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("three").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("three").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("two").
+					Parent("three").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("two").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("one").
+					Parent("two").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("one").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+			}
+			testCq := utiltesting.MakeClusterQueue("test-clusterqueue").
+				Cohort("one").
+				Preemption(kueue.ClusterQueuePreemption{
+					WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+					ReclaimWithinCohort: kueue.PreemptionPolicyLowerPriority,
+				}).
+				ResourceGroup(
+					utiltesting.MakeFlavorQuotas("one").Resource(corev1.ResourceCPU, "0").FlavorQuotas,
+					utiltesting.MakeFlavorQuotas("two").Resource(corev1.ResourceCPU, "0").FlavorQuotas,
+					utiltesting.MakeFlavorQuotas("three").Resource(corev1.ResourceCPU, "0").FlavorQuotas,
+				).
+				FlavorFungibility(kueue.FlavorFungibility{
+					WhenCanPreempt: kueue.TryNextFlavor,
+				}).ClusterQueue
+			otherCq := utiltesting.MakeClusterQueue("other-clusterqueue").
+				Cohort("two").ResourceGroup(
+				utiltesting.MakeFlavorQuotas("one").Resource(corev1.ResourceCPU, "0").FlavorQuotas,
+				utiltesting.MakeFlavorQuotas("two").Resource(corev1.ResourceCPU, "0").FlavorQuotas,
+				utiltesting.MakeFlavorQuotas("three").Resource(corev1.ResourceCPU, "0").FlavorQuotas,
+			).ClusterQueue
+
+			wlInfo := workload.NewInfo(&kueue.Workload{
+				Spec: kueue.WorkloadSpec{
+					PodSets: []kueue.PodSet{
+						tc.workloadRequests.PodSet,
+					},
+				},
+			})
+
+			if tc.flavorFungibility != nil {
+				testCq.Spec.FlavorFungibility = tc.flavorFungibility
+			}
+			cache := cache.New(utiltesting.NewFakeClient())
+			for _, cohort := range cohorts {
+				if err := cache.AddOrUpdateCohort(cohort); err != nil {
+					t.Fatalf("Couldn't add Cohort to cache: %v", err)
+				}
+			}
+			if err := cache.AddClusterQueue(ctx, &testCq); err != nil {
+				t.Fatalf("Failed to add CQ to cache")
+			}
+			if err := cache.AddClusterQueue(ctx, &otherCq); err != nil {
+				t.Fatalf("Failed to add CQ to cache")
+			}
+			for _, rf := range resourceFlavors {
+				cache.AddOrUpdateResourceFlavor(rf)
+			}
+
+			snapshot, err := cache.Snapshot(ctx)
+			if err != nil {
+				t.Fatalf("unexpected error while building snapshot: %v", err)
+			}
+			otherClusterQueue := snapshot.ClusterQueue("other-clusterqueue")
+			otherClusterQueue.AddUsage(workload.Usage{Quota: tc.otherClusterQueueUsage})
+
+			testClusterQueue := snapshot.ClusterQueue("test-clusterqueue")
+			testClusterQueue.AddUsage(workload.Usage{Quota: tc.testClusterQueueUsage})
+
+			flvAssigner := New(wlInfo, testClusterQueue, resourceFlavors, false, &testOracle{})
+			log := testr.NewWithOptions(t, testr.Options{Verbosity: 2})
+			assignment := flvAssigner.Assign(log, nil)
+			if gotRepMode := assignment.RepresentativeMode(); gotRepMode != tc.wantMode {
+				t.Errorf("Unexpected RepresentativeMode. got %s, want %s", gotRepMode, tc.wantMode)
+			}
+			if len(assignment.PodSets[0].Flavors) != len(tc.wantAssigment) {
+				t.Errorf("Wrong number of flavors. got %d, want %d", len(assignment.PodSets[0].Flavors), len(tc.wantAssigment))
+			}
+			for resourceName, wantFlavor := range tc.wantAssigment {
+				if gotFlavor := assignment.PodSets[0].Flavors[resourceName].Name; gotFlavor != wantFlavor {
+					t.Errorf("Unexpected flavor. got %s, want %s", gotFlavor, wantFlavor)
+				}
+			}
+		})
+	}
+}
diff --git a/pkg/scheduler/preemption/preemption_test.go b/pkg/scheduler/preemption/preemption_test.go
index 119f81ab1..06dab3a74 100644
--- a/pkg/scheduler/preemption/preemption_test.go
+++ b/pkg/scheduler/preemption/preemption_test.go
@@ -2729,7 +2729,6 @@ func TestFairPreemptions(t *testing.T) {
 func targetKeyReason(key, reason string) string {
 	return fmt.Sprintf("%s:%s", key, reason)
 }
-
 func TestCandidatesOrdering(t *testing.T) {
 	now := time.Now()
 	candidates := []*workload.Info{
@@ -2764,7 +2763,7 @@ func TestCandidatesOrdering(t *testing.T) {
 			ReserveQuotaAt(utiltesting.MakeAdmission("self").Obj(), now.Add(time.Second)).
 			Obj()),
 	}
-	sort.Slice(candidates, candidatesOrdering(candidates, "self", now))
+	sort.Slice(candidates, CandidatesOrdering(candidates, "self", now))
 	gotNames := make([]string, len(candidates))
 	for i, c := range candidates {
 		gotNames[i] = workload.Key(c.Obj)
@@ -2816,3 +2815,1207 @@ func TestPreemptionMessage(t *testing.T) {
 		}
 	}
 }
+
+func TestHierarchicalPreemptions(t *testing.T) {
+	now := time.Now()
+	flavors := []*kueue.ResourceFlavor{
+		utiltesting.MakeResourceFlavor("default").Obj(),
+	}
+	cases := map[string]struct {
+		clusterQueues []*kueue.ClusterQueue
+		cohorts       []*kueuealpha.Cohort
+		admitted      []kueue.Workload
+		incoming      *kueue.Workload
+		targetCQ      kueue.ClusterQueueReference
+		assignment    flavorassigner.Assignment
+		wantPreempted sets.Set[string]
+	}{
+		//
+		//            R
+		//      /      |
+		//   C(2) q_borrowing(0)
+		//  /
+		// q
+		"preempt with hierarchical advantage": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted2", "").
+					Priority(0).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "2").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(targetKeyReason("/admitted2", kueue.InCohortReclamationReason)),
+		},
+		//
+		//             R
+		//      /      |         \
+		//   C(2) q_borrowing(0)  q_nominal(2)
+		//  /
+		// q
+		"avoid queues within nominal quota": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q_nominal").
+					Cohort("r").ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+					Resource(corev1.ResourceCPU, "2").
+					Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted1", "").
+					Priority(-10).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_nominal").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted2", "").
+					Priority(0).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "2").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(targetKeyReason("/admitted2", kueue.InCohortReclamationReason)),
+		},
+		//
+		//            R(0)
+		//      /      |
+		//   C(2) q_borrowing(0)
+		//  /
+		// q(0)
+		"preempt multiple with hierarchical advantage": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted1", "").
+					Priority(1).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted2", "").
+					Priority(2).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "2").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted1", kueue.InCohortReclamationReason),
+				targetKeyReason("/admitted2", kueue.InCohortReclamationReason)),
+		},
+		//
+		//        R(0)
+		//      /
+		//   C(3)
+		//  /   \
+		// q(0) q_same_cohort(0)
+		"preempt in cohort and own CQ": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "3").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+						BorrowWithinCohort: &kueue.BorrowWithinCohort{
+							Policy:               kueue.BorrowWithinCohortPolicyLowerPriority,
+							MaxPriorityThreshold: ptr.To[int32](0),
+						},
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_same_cohort").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_not_preemptible", "").
+					Priority(1).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_same_cohort").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_preemptible", "").
+					Priority(0).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_same_cohort").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_own_queue", "").
+					Priority(-1).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(1).
+				Request(corev1.ResourceCPU, "2").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_preemptible", kueue.InCohortReclaimWhileBorrowingReason),
+				targetKeyReason("/admitted_own_queue", kueue.InClusterQueueReason)),
+		},
+		//
+		//            R(0)
+		//      /      |
+		//   C(2) q_borrowing(0)
+		//  /
+		// q(0)
+		"prefer to preempt hierarchical candidate": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing", "").
+					Priority(1).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_same_queue", "").
+					Priority(-2).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "1").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_borrowing", kueue.InCohortReclamationReason)),
+		},
+		//
+		//           R(0)
+		//      /      |
+		//   C(2)   q_nominal(2)
+		//  /   \
+		// q(0) q_same_cohort(0)
+		"forced to preempt priority candidate": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+						BorrowWithinCohort: &kueue.BorrowWithinCohort{
+							Policy:               kueue.BorrowWithinCohortPolicyLowerPriority,
+							MaxPriorityThreshold: ptr.To[int32](0),
+						},
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_nominal").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_same_cohort").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_nominal", "").
+					Priority(-10).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_nominal").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_same_cohort", "").
+					Priority(-1).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_same_cohort").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "2").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_same_cohort", kueue.InCohortReclaimWhileBorrowingReason)),
+		},
+		//
+		//           R(0)
+		//      /      |
+		//   C(2)   q_borrowing(0)
+		//  /    \
+		// q(4)  q_same_cohort(0)
+		//
+		"incoming workload fits in CQ nominal quota": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "4").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_same_cohort").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing", "").
+					Priority(10).
+					Request(corev1.ResourceCPU, "3").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "3").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_same_cohort", "").
+					Priority(10).
+					Request(corev1.ResourceCPU, "3").
+					ReserveQuota(utiltesting.MakeAdmission("q_same_cohort").
+						Assignment(corev1.ResourceCPU, "default", "3").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "4").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_borrowing", kueue.InCohortReclamationReason),
+				targetKeyReason("/admitted_same_cohort", kueue.InCohortReclamationReason)),
+		},
+		//
+		//           R(1)
+		//      /      |
+		//   C(4)   q_borrowing(0)
+		//  /    \
+		// q(0)  q_same_cohort(0)
+		//
+		"preempt hierarchical and priority candidates": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+					Resource(corev1.ResourceCPU, "1").
+					Obj()).Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyLowerPriority,
+						BorrowWithinCohort: &kueue.BorrowWithinCohort{
+							Policy:               kueue.BorrowWithinCohortPolicyLowerPriority,
+							MaxPriorityThreshold: ptr.To[int32](0),
+						},
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_same_cohort").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing", "").
+					Priority(-1).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_same_cohort_preemptible", "").
+					Priority(-1).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_same_cohort").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_not_preemptible", "").
+					Priority(1).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "3").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_borrowing", kueue.InCohortReclamationReason),
+				targetKeyReason("/admitted_same_cohort_preemptible", kueue.InCohortReclaimWhileBorrowingReason)),
+		},
+		//
+		//           R(1)
+		//      /      |
+		//   C(4)   q_borrowing(0)
+		//  /    \
+		// q(0)  q_same_cohort(0)
+		//
+		"preempt hierarchical candidates and inside CQ": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+					Resource(corev1.ResourceCPU, "1").
+					Obj()).Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyLowerPriority,
+						BorrowWithinCohort: &kueue.BorrowWithinCohort{
+							Policy:               kueue.BorrowWithinCohortPolicyLowerPriority,
+							MaxPriorityThreshold: ptr.To[int32](0),
+						},
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_same_cohort").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing", "").
+					Priority(-1).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_same_queue_preemptible", "").
+					Priority(-1).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_not_preemptible", "").
+					Priority(1).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "3").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_borrowing", kueue.InCohortReclamationReason),
+				targetKeyReason("/admitted_same_queue_preemptible", kueue.InClusterQueueReason)),
+		},
+		//
+		//            R(0)
+		//      /      |          \
+		//   C(3) q_borrowing(0)  q_nominal(2)
+		//  /
+		// q(0)
+		"reclaim nominal quota from lowest priority workload, excluding non-borrowing": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "3").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_nominal").
+					Cohort("r").ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+					Resource(corev1.ResourceCPU, "2").
+					Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing_prio_8", "").
+					Priority(8).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_prio_9", "").
+					Priority(9).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_prio_10", "").
+					Priority(9).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_nominal", "").
+					Priority(-2).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_nominal").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "1").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_borrowing_prio_8", kueue.InCohortReclamationReason)),
+		},
+		//
+		//                  R
+		//            /            \
+		//      C(2)                   C_other(2)
+		//     /    \                     |
+		//    q(0)  q_same_cohort(0)   q_other(0)
+		"infeasible preemption all available workloads in pruned subtrees": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("c_other").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q_other").
+					Cohort("c_other").ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+					Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_same_cohort").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_other_1", "").
+					Priority(-10).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_other").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_other_2", "").
+					Priority(-10).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_other").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_same_cohort", "").
+					Priority(0).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q_same_cohort").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "2").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New[string](),
+		},
+		//
+		//          R(3CPU, 0Gi)
+		//      /      |
+		//   C(4CPU,4Gi) q_borrowing(0)
+		//  /    \
+		// q(0)   q_same_cohort(0)
+		"hiearchical preemption with multiple resources": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "3").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Resource(corev1.ResourceMemory, "4Gi").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_same_cohort").
+					Cohort("c").ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+					Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing", "").
+					Priority(0).
+					Request(corev1.ResourceCPU, "3").
+					Request(corev1.ResourceMemory, "1Gi").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "3").
+						Assignment(corev1.ResourceMemory, "default", "1Gi").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_same_cohort", "").
+					Priority(-2).
+					Request(corev1.ResourceCPU, "1").
+					Request(corev1.ResourceMemory, "3Gi").
+					ReserveQuota(utiltesting.MakeAdmission("q_same_cohort").
+						Assignment(corev1.ResourceCPU, "default", "1").
+						Assignment(corev1.ResourceMemory, "default", "3Gi").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(-2).
+				Request(corev1.ResourceCPU, "2").
+				Request(corev1.ResourceMemory, "1Gi").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+				corev1.ResourceMemory: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(targetKeyReason("/admitted_borrowing", kueue.InCohortReclamationReason)),
+		},
+		//
+		//           R(0)
+		//      /      |
+		//   C(2)   q_borrowing(0)
+		//  /    \
+		// q(0)  q_same_cohort(0)
+		//
+		"prefer to preempt evicted workloads": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+						BorrowWithinCohort: &kueue.BorrowWithinCohort{
+							Policy:               kueue.BorrowWithinCohortPolicyLowerPriority,
+							MaxPriorityThreshold: ptr.To[int32](0),
+						},
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_same_cohort").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing", "").
+					Priority(-10).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("evicted_same_cohort", "").
+					Priority(-1).
+					Request(corev1.ResourceCPU, "1").
+					ReserveQuota(utiltesting.MakeAdmission("q_same_cohort").
+						Assignment(corev1.ResourceCPU, "default", "1").Obj()).
+					SetOrReplaceCondition(metav1.Condition{
+						Type:               kueue.WorkloadEvicted,
+						Status:             metav1.ConditionTrue,
+						LastTransitionTime: metav1.NewTime(now),
+					}).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(0).
+				Request(corev1.ResourceCPU, "1").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New[string](),
+		},
+		//
+		//           R(0)
+		//      /      |
+		//   C(2)   q_borrowing(0)
+		//  /
+		// q(3, lending limit 2)
+		//
+		"respect lending limits": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "2").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q").
+					Cohort("c").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "3", "", "2").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+				utiltesting.MakeClusterQueue("q_borrowing").
+					Cohort("r").ResourceGroup(
+					*utiltesting.MakeFlavorQuotas("default").Obj()).
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing", "").
+					Priority(0).
+					Request(corev1.ResourceCPU, "4").
+					ReserveQuota(utiltesting.MakeAdmission("q_borrowing").
+						Assignment(corev1.ResourceCPU, "default", "4").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(-2).
+				Request(corev1.ResourceCPU, "5").
+				Obj(),
+			targetCQ: "q",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_borrowing", kueue.InCohortReclamationReason)),
+		},
+		//                                r
+		//                             /      \
+		//                          c11        c12
+		//                       /   |   \       \
+		//                    c21   c22    c23    q1
+		//                  /  |     |     |
+		//                c31  c32   q3    q2
+		//              /      |
+		//            q5       q4
+		//	quotas:
+		//	4: c11, c12, c21, c22, c23, c32, c31
+		//	0: q1, q3, q4, q5
+		"reclaim in complex hierarchy": {
+			cohorts: []*kueuealpha.Cohort{
+				utiltesting.MakeCohort("r").Obj(),
+				utiltesting.MakeCohort("c11").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("c12").
+					Parent("r").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("c21").
+					Parent("c11").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("c22").
+					Parent("c11").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("c23").
+					Parent("c11").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("c31").
+					Parent("c21").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+				utiltesting.MakeCohort("c32").
+					Parent("c21").
+					ResourceGroup(*utiltesting.MakeFlavorQuotas("default").
+						Resource(corev1.ResourceCPU, "4").
+						Obj()).Obj(),
+			},
+			clusterQueues: []*kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("q1").
+					Cohort("c12").
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).
+					Obj(),
+				utiltesting.MakeClusterQueue("q2").
+					Cohort("c23").
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).
+					Obj(),
+				utiltesting.MakeClusterQueue("q3").
+					Cohort("c22").
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).
+					Obj(),
+				utiltesting.MakeClusterQueue("q4").
+					Cohort("c32").
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).
+					Obj(),
+				utiltesting.MakeClusterQueue("q5").
+					Cohort("c31").
+					Preemption(kueue.ClusterQueuePreemption{
+						WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+						ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+					}).
+					Obj(),
+			},
+			admitted: []kueue.Workload{
+				*utiltesting.MakeWorkload("admitted_borrowing_1", "").
+					Priority(-6).
+					Request(corev1.ResourceCPU, "4").
+					ReserveQuota(utiltesting.MakeAdmission("q1").
+						Assignment(corev1.ResourceCPU, "default", "4").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_2", "").
+					Priority(-5).
+					Request(corev1.ResourceCPU, "4").
+					ReserveQuota(utiltesting.MakeAdmission("q1").
+						Assignment(corev1.ResourceCPU, "default", "4").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_3", "").
+					Priority(-9).
+					Request(corev1.ResourceCPU, "4").
+					ReserveQuota(utiltesting.MakeAdmission("q2").
+						Assignment(corev1.ResourceCPU, "default", "4").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_4", "").
+					Priority(-10).
+					Request(corev1.ResourceCPU, "4").
+					ReserveQuota(utiltesting.MakeAdmission("q2").
+						Assignment(corev1.ResourceCPU, "default", "4").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_5", "").
+					Priority(-4).
+					Request(corev1.ResourceCPU, "4").
+					ReserveQuota(utiltesting.MakeAdmission("q3").
+						Assignment(corev1.ResourceCPU, "default", "4").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_6", "").
+					Priority(-3).
+					Request(corev1.ResourceCPU, "3").
+					ReserveQuota(utiltesting.MakeAdmission("q3").
+						Assignment(corev1.ResourceCPU, "default", "3").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_7", "").
+					Priority(4).
+					Request(corev1.ResourceCPU, "2").
+					ReserveQuota(utiltesting.MakeAdmission("q4").
+						Assignment(corev1.ResourceCPU, "default", "2").Obj()).
+					Obj(),
+				*utiltesting.MakeWorkload("admitted_borrowing_8", "").
+					Priority(2).
+					Request(corev1.ResourceCPU, "3").
+					ReserveQuota(utiltesting.MakeAdmission("q4").
+						Assignment(corev1.ResourceCPU, "default", "3").Obj()).
+					Obj(),
+			},
+			incoming: utiltesting.MakeWorkload("incoming", "").
+				Priority(-2).
+				Request(corev1.ResourceCPU, "7").
+				Obj(),
+			targetCQ: "q5",
+			assignment: singlePodSetAssignment(flavorassigner.ResourceAssignment{
+				corev1.ResourceCPU: &flavorassigner.FlavorAssignment{
+					Name: "default",
+					Mode: flavorassigner.Preempt,
+				},
+			}),
+			// only one of workloads from q2 will be preempted because
+			// after preempting the first one, the usage of cohort
+			// c23 will be back within nominal quota
+			wantPreempted: sets.New(
+				targetKeyReason("/admitted_borrowing_1", kueue.InCohortReclamationReason),
+				targetKeyReason("/admitted_borrowing_4", kueue.InCohortReclamationReason)),
+		},
+	}
+	for name, tc := range cases {
+		t.Run(name, func(t *testing.T) {
+			ctx, log := utiltesting.ContextWithLog(t)
+			cl := utiltesting.NewClientBuilder().
+				WithLists(&kueue.WorkloadList{Items: tc.admitted}).
+				Build()
+
+			cqCache := cache.New(cl)
+			for _, flv := range flavors {
+				cqCache.AddOrUpdateResourceFlavor(flv)
+			}
+			for _, cq := range tc.clusterQueues {
+				if err := cqCache.AddClusterQueue(ctx, cq); err != nil {
+					t.Fatalf("Couldn't add ClusterQueue to cache: %v", err)
+				}
+			}
+			for _, cohort := range tc.cohorts {
+				if err := cqCache.AddOrUpdateCohort(cohort); err != nil {
+					t.Fatalf("Couldn't add Cohort to cache: %v", err)
+				}
+			}
+
+			var lock sync.Mutex
+			gotPreempted := sets.New[string]()
+			broadcaster := record.NewBroadcaster()
+			scheme := runtime.NewScheme()
+			if err := kueue.AddToScheme(scheme); err != nil {
+				t.Fatalf("Failed adding kueue scheme: %v", err)
+			}
+			recorder := broadcaster.NewRecorder(scheme, corev1.EventSource{Component: constants.AdmissionName})
+			preemptor := New(cl, workload.Ordering{}, recorder, config.FairSharing{}, clocktesting.NewFakeClock(now))
+			preemptor.applyPreemption = func(ctx context.Context, w *kueue.Workload, reason, _ string) error {
+				lock.Lock()
+				gotPreempted.Insert(targetKeyReason(workload.Key(w), reason))
+				lock.Unlock()
+				return nil
+			}
+			beforeSnapshot, err := cqCache.Snapshot(ctx)
+			if err != nil {
+				t.Fatalf("unexpected error while building snapshot: %v", err)
+			}
+			// make a working copy of the snapshotWorkingCopy than preemption can temporarily modify
+			snapshotWorkingCopy, err := cqCache.Snapshot(ctx)
+			if err != nil {
+				t.Fatalf("unexpected error while building snapshot: %v", err)
+			}
+			wlInfo := workload.NewInfo(tc.incoming)
+			wlInfo.ClusterQueue = tc.targetCQ
+			targets := preemptor.GetTargets(log, *wlInfo, tc.assignment, snapshotWorkingCopy)
+			_, err = preemptor.IssuePreemptions(ctx, wlInfo, targets)
+			if err != nil {
+				t.Fatalf("Failed doing preemption")
+			}
+			if diff := cmp.Diff(tc.wantPreempted, gotPreempted, cmpopts.EquateEmpty()); diff != "" {
+				t.Errorf("Issued preemptions (-want,+got):\n%s", diff)
+			}
+			if diff := cmp.Diff(beforeSnapshot, snapshotWorkingCopy, snapCmpOpts); diff != "" {
+				t.Errorf("Snapshot was modified (-initial,+end):\n%s", diff)
+			}
+		})
+	}
+}
diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go
index be9486c34..e1114d496 100644
--- a/pkg/scheduler/scheduler_test.go
+++ b/pkg/scheduler/scheduler_test.go
@@ -3043,6 +3043,69 @@ func TestSchedule(t *testing.T) {
 				"eng-alpha/a1-admitted": *utiltesting.MakeAdmission("ClusterQueueA").Assignment("gpu", "on-demand", "1").Obj(),
 			},
 		},
+		//
+		// Denote Cohorts in UPPERCASE, and ClusterQueues in lowercase.
+		// quota is at GUARANTEED cohort
+		//
+		//             ROOT
+		//          /        \
+		//    GUARANTEED      best-effort
+		//   /
+		// guaranteed
+		//
+		"in a hierarchical cohort, workload borrowing less is scheduled first": {
+			cohorts: []kueuealpha.Cohort{
+				utiltesting.MakeCohort("root").Cohort,
+				utiltesting.MakeCohort("guaranteed").
+					ResourceGroup(
+						*utiltesting.MakeFlavorQuotas("default").
+							Resource(corev1.ResourceCPU, "4").Obj(),
+					).Parent("root").Cohort,
+			},
+			additionalClusterQueues: []kueue.ClusterQueue{
+				utiltesting.MakeClusterQueue("guaranteed").
+					Cohort("guaranteed").
+					ResourceGroup(
+						*utiltesting.MakeFlavorQuotas("default").
+							Resource(corev1.ResourceCPU, "0").Obj(),
+					).
+					ClusterQueue,
+				utiltesting.MakeClusterQueue("best-effort").
+					Cohort("root").
+					ResourceGroup(
+						*utiltesting.MakeFlavorQuotas("default").
+							Resource(corev1.ResourceCPU, "0").Obj(),
+					).
+					ClusterQueue,
+			},
+			additionalLocalQueues: []kueue.LocalQueue{
+				*utiltesting.MakeLocalQueue("lq-guaranteed", "eng-alpha").ClusterQueue("guaranteed").Obj(),
+				*utiltesting.MakeLocalQueue("lq-best-effort", "eng-alpha").ClusterQueue("best-effort").Obj(),
+			},
+			workloads: []kueue.Workload{
+				utiltesting.MakeWorkload("guaranteed", "eng-alpha").
+					Queue("lq-guaranteed").
+					Priority(0).
+					PodSets(utiltesting.MakePodSet("one", 1).
+						Request(corev1.ResourceCPU, "4").
+						PodSet).
+					Workload,
+				utiltesting.MakeWorkload("best-effort", "eng-alpha").
+					Queue("lq-best-effort").
+					Priority(3).
+					PodSets(utiltesting.MakePodSet("one", 1).
+						Request(corev1.ResourceCPU, "4").
+						PodSet).
+					Workload,
+			},
+			wantAssignments: map[string]kueue.Admission{
+				"eng-alpha/guaranteed": *utiltesting.MakeAdmission("guaranteed", "one").Assignment(corev1.ResourceCPU, "default", "4").Obj(),
+			},
+			wantScheduled: []string{"eng-alpha/guaranteed"},
+			wantLeft: map[kueue.ClusterQueueReference][]string{
+				"best-effort": {"eng-alpha/best-effort"},
+			},
+		},
 	}
 
 	for name, tc := range cases {
@@ -3219,7 +3282,7 @@ func TestEntryOrdering(t *testing.T) {
 				}},
 			},
 			assignment: flavorassigner.Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 			},
 		},
 		{
@@ -3248,7 +3311,7 @@ func TestEntryOrdering(t *testing.T) {
 				}},
 			},
 			assignment: flavorassigner.Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 			},
 		},
 		{
@@ -3269,7 +3332,7 @@ func TestEntryOrdering(t *testing.T) {
 				}},
 			},
 			assignment: flavorassigner.Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 			},
 		},
 		{
@@ -3292,7 +3355,7 @@ func TestEntryOrdering(t *testing.T) {
 				},
 			},
 			assignment: flavorassigner.Assignment{
-				Borrowing: true,
+				Borrowing: 1,
 			},
 		},
 		{
@@ -3315,6 +3378,19 @@ func TestEntryOrdering(t *testing.T) {
 				},
 			},
 		},
+		{
+			Info: workload.Info{
+				Obj: &kueue.Workload{ObjectMeta: metav1.ObjectMeta{
+					Name:              "high_pri_borrowing_more",
+					CreationTimestamp: metav1.NewTime(now.Add(3 * time.Second)),
+				}, Spec: kueue.WorkloadSpec{
+					Priority: ptr.To[int32](1),
+				}},
+			},
+			assignment: flavorassigner.Assignment{
+				Borrowing: 2,
+			},
+		},
 	}
 	inputForOrderingPreemptedWorkloads := []entry{
 		{
@@ -3407,28 +3483,28 @@ func TestEntryOrdering(t *testing.T) {
 			input:            input,
 			prioritySorting:  true,
 			workloadOrdering: workload.Ordering{PodsReadyRequeuingTimestamp: config.EvictionTimestamp},
-			wantOrder:        []string{"new_high_pri", "old", "recently_evicted", "new", "high_pri_borrowing", "old_borrowing", "evicted_borrowing", "new_borrowing"},
+			wantOrder:        []string{"new_high_pri", "old", "recently_evicted", "new", "high_pri_borrowing", "old_borrowing", "evicted_borrowing", "new_borrowing", "high_pri_borrowing_more"},
 		},
 		{
 			name:             "Priority sorting is enabled (default) using pods-ready Creation timestamp",
 			input:            input,
 			prioritySorting:  true,
 			workloadOrdering: workload.Ordering{PodsReadyRequeuingTimestamp: config.CreationTimestamp},
-			wantOrder:        []string{"new_high_pri", "recently_evicted", "old", "new", "high_pri_borrowing", "old_borrowing", "evicted_borrowing", "new_borrowing"},
+			wantOrder:        []string{"new_high_pri", "recently_evicted", "old", "new", "high_pri_borrowing", "old_borrowing", "evicted_borrowing", "new_borrowing", "high_pri_borrowing_more"},
 		},
 		{
 			name:             "Priority sorting is disabled using pods-ready Eviction timestamp",
 			input:            input,
 			prioritySorting:  false,
 			workloadOrdering: workload.Ordering{PodsReadyRequeuingTimestamp: config.EvictionTimestamp},
-			wantOrder:        []string{"old", "recently_evicted", "new", "new_high_pri", "old_borrowing", "evicted_borrowing", "high_pri_borrowing", "new_borrowing"},
+			wantOrder:        []string{"old", "recently_evicted", "new", "new_high_pri", "old_borrowing", "evicted_borrowing", "high_pri_borrowing", "new_borrowing", "high_pri_borrowing_more"},
 		},
 		{
 			name:             "Priority sorting is disabled using pods-ready Creation timestamp",
 			input:            input,
 			prioritySorting:  false,
 			workloadOrdering: workload.Ordering{PodsReadyRequeuingTimestamp: config.CreationTimestamp},
-			wantOrder:        []string{"recently_evicted", "old", "new", "new_high_pri", "old_borrowing", "evicted_borrowing", "high_pri_borrowing", "new_borrowing"},
+			wantOrder:        []string{"recently_evicted", "old", "new", "new_high_pri", "old_borrowing", "evicted_borrowing", "high_pri_borrowing", "new_borrowing", "high_pri_borrowing_more"},
 		},
 		{
 			name:            "Some workloads are preempted; Priority sorting is disabled",
@@ -4149,7 +4225,7 @@ func TestResourcesToReserve(t *testing.T) {
 	cases := []struct {
 		name            string
 		assignmentMode  flavorassigner.FlavorAssignmentMode
-		borrowing       bool
+		borrowing       int
 		assignmentUsage resources.FlavorResourceQuantities
 		cqUsage         resources.FlavorResourceQuantities
 		wantReserved    resources.FlavorResourceQuantities
@@ -4229,7 +4305,7 @@ func TestResourcesToReserve(t *testing.T) {
 		{
 			name:           "Reserved memory cut by nominal+borrowing quota, assignment preempts and borrows",
 			assignmentMode: flavorassigner.Preempt,
-			borrowing:      true,
+			borrowing:      1,
 			assignmentUsage: resources.FlavorResourceQuantities{
 				{Flavor: kueue.ResourceFlavorReference("spot"), Resource: corev1.ResourceMemory}: 50,
 				{Flavor: kueue.ResourceFlavorReference("model-b"), Resource: "gpu"}:              2,
@@ -4248,7 +4324,7 @@ func TestResourcesToReserve(t *testing.T) {
 		{
 			name:           "Reserved memory equal assignment usage, CQ borrowing limit is nil",
 			assignmentMode: flavorassigner.Preempt,
-			borrowing:      true,
+			borrowing:      1,
 			assignmentUsage: resources.FlavorResourceQuantities{
 				{Flavor: kueue.ResourceFlavorReference("on-demand"), Resource: corev1.ResourceMemory}: 50,
 				{Flavor: kueue.ResourceFlavorReference("model-b"), Resource: "gpu"}:                   2,
diff --git a/pkg/util/admissioncheck/admissioncheck_test.go b/pkg/util/admissioncheck/admissioncheck_test.go
index aa83128c2..4607821fc 100644
--- a/pkg/util/admissioncheck/admissioncheck_test.go
+++ b/pkg/util/admissioncheck/admissioncheck_test.go
@@ -113,7 +113,7 @@ func TestConfigHelper(t *testing.T) {
 				t.Fatalf("cannot built the helper: %s", err)
 			}
 
-			gotConfig, gotError := helper.ConfigForAdmissionCheck(ctx, tc.targetAdmissionCheck)
+			gotConfig, gotError := helper.ConfigForAdmissionCheck(ctx, kueue.AdmissionCheckReference(tc.targetAdmissionCheck))
 			if diff := cmp.Diff(tc.wantError, gotError, cmpopts.EquateErrors()); diff != "" {
 				t.Errorf("unexpected config (-want/+got):\n%s", diff)
 			}
@@ -172,11 +172,10 @@ func TestFilterCheckStates(t *testing.T) {
 	cases := map[string]struct {
 		admissionchecks []kueue.AdmissionCheck
 		states          []kueue.AdmissionCheckState
-		wantResult      []string
+		wantResult      []kueue.AdmissionCheckReference
 	}{
 		"empty": {},
 		"no match": {
-
 			states: []kueue.AdmissionCheckState{
 				{Name: "check1"},
 				{Name: "check2"},
@@ -194,7 +193,7 @@ func TestFilterCheckStates(t *testing.T) {
 				{Name: "check2"},
 				{Name: "check3"},
 			},
-			wantResult: []string{"check1", "check3"},
+			wantResult: []kueue.AdmissionCheckReference{"check1", "check3"},
 		},
 	}
 
diff --git a/pkg/util/testing/wrappers.go b/pkg/util/testing/wrappers.go
index bf4a8cc18..721d98822 100644
--- a/pkg/util/testing/wrappers.go
+++ b/pkg/util/testing/wrappers.go
@@ -810,7 +810,7 @@ func (c *ClusterQueueWrapper) ResourceGroup(flavors ...kueue.FlavorQuotas) *Clus
 }
 
 // AdmissionChecks replaces the queue additional checks
-func (c *ClusterQueueWrapper) AdmissionChecks(checks ...string) *ClusterQueueWrapper {
+func (c *ClusterQueueWrapper) AdmissionChecks(checks ...kueue.AdmissionCheckReference) *ClusterQueueWrapper {
 	c.Spec.AdmissionChecks = checks
 	return c
 }
@@ -1152,7 +1152,7 @@ type AdmissionCheckStrategyRuleWrapper struct {
 	kueue.AdmissionCheckStrategyRule
 }
 
-func MakeAdmissionCheckStrategyRule(name string, flavors ...kueue.ResourceFlavorReference) *AdmissionCheckStrategyRuleWrapper {
+func MakeAdmissionCheckStrategyRule(name kueue.AdmissionCheckReference, flavors ...kueue.ResourceFlavorReference) *AdmissionCheckStrategyRuleWrapper {
 	if len(flavors) == 0 {
 		flavors = make([]kueue.ResourceFlavorReference, 0)
 	}
@@ -1208,38 +1208,6 @@ func (ac *AdmissionCheckWrapper) Parameters(apigroup, kind, name string) *Admiss
 	return ac
 }
 
-func (ac *AdmissionCheckWrapper) SingleInstanceInClusterQueue(singleInstance bool, reason, message string, observedGeneration int64) *AdmissionCheckWrapper {
-	cond := metav1.Condition{
-		Type:               kueue.AdmissionChecksSingleInstanceInClusterQueue,
-		Status:             metav1.ConditionTrue,
-		Reason:             reason,
-		Message:            message,
-		ObservedGeneration: observedGeneration,
-	}
-	if !singleInstance {
-		cond.Status = metav1.ConditionFalse
-	}
-
-	apimeta.SetStatusCondition(&ac.Status.Conditions, cond)
-	return ac
-}
-
-func (ac *AdmissionCheckWrapper) ApplyToAllFlavors(applyToAllFlavors bool, reason, message string, observedGeneration int64) *AdmissionCheckWrapper {
-	cond := metav1.Condition{
-		Type:               kueue.FlavorIndependentAdmissionCheck,
-		Status:             metav1.ConditionTrue,
-		Reason:             reason,
-		Message:            message,
-		ObservedGeneration: observedGeneration,
-	}
-	if !applyToAllFlavors {
-		cond.Status = metav1.ConditionFalse
-	}
-
-	apimeta.SetStatusCondition(&ac.Status.Conditions, cond)
-	return ac
-}
-
 func (ac *AdmissionCheckWrapper) Obj() *kueue.AdmissionCheck {
 	return &ac.AdmissionCheck
 }
diff --git a/pkg/util/testingjobs/appwrapper/wrappers.go b/pkg/util/testingjobs/appwrapper/wrappers.go
index 81d06a0ac..a55297988 100644
--- a/pkg/util/testingjobs/appwrapper/wrappers.go
+++ b/pkg/util/testingjobs/appwrapper/wrappers.go
@@ -29,6 +29,7 @@ import (
 	"k8s.io/utils/ptr"
 
 	"sigs.k8s.io/kueue/pkg/controller/constants"
+	"sigs.k8s.io/kueue/pkg/util/testing"
 )
 
 // AppWrapperWrapper wraps an AppWrapper.
@@ -97,13 +98,7 @@ func (aw *AppWrapperWrapper) UID(uid string) *AppWrapperWrapper {
 
 // OwnerReference adds a ownerReference to the default container.
 func (aw *AppWrapperWrapper) OwnerReference(ownerName string, ownerGVK schema.GroupVersionKind) *AppWrapperWrapper {
-	aw.ObjectMeta.OwnerReferences = append(aw.ObjectMeta.OwnerReferences, metav1.OwnerReference{
-		APIVersion: ownerGVK.GroupVersion().String(),
-		Kind:       ownerGVK.Kind,
-		Name:       ownerName,
-		UID:        types.UID(ownerName),
-		Controller: ptr.To(true),
-	})
+	testing.AppendOwnerReference(&aw.AppWrapper, ownerGVK, ownerName, ownerName, ptr.To(true), ptr.To(true))
 	return aw
 }
 
diff --git a/pkg/util/testingjobs/job/wrappers.go b/pkg/util/testingjobs/job/wrappers.go
index 5b4ac1cb2..2c2ebbe51 100644
--- a/pkg/util/testingjobs/job/wrappers.go
+++ b/pkg/util/testingjobs/job/wrappers.go
@@ -28,6 +28,7 @@ import (
 	"k8s.io/utils/ptr"
 
 	"sigs.k8s.io/kueue/pkg/controller/constants"
+	"sigs.k8s.io/kueue/pkg/util/testing"
 )
 
 // JobWrapper wraps a Job.
@@ -76,6 +77,16 @@ func (j *JobWrapper) BackoffLimit(limit int32) *JobWrapper {
 	return j
 }
 
+func (j *JobWrapper) BackoffLimitPerIndex(limit int32) *JobWrapper {
+	j.Spec.BackoffLimitPerIndex = ptr.To(limit)
+	return j
+}
+
+func (j *JobWrapper) CompletionMode(mode batchv1.CompletionMode) *JobWrapper {
+	j.Spec.CompletionMode = &mode
+	return j
+}
+
 func (j *JobWrapper) TerminationGracePeriod(seconds int64) *JobWrapper {
 	j.Spec.Template.Spec.TerminationGracePeriodSeconds = ptr.To(seconds)
 	return j
@@ -199,15 +210,7 @@ func (j *JobWrapper) Image(image string, args []string) *JobWrapper {
 
 // OwnerReference adds a ownerReference to the default container.
 func (j *JobWrapper) OwnerReference(ownerName string, ownerGVK schema.GroupVersionKind) *JobWrapper {
-	j.ObjectMeta.OwnerReferences = []metav1.OwnerReference{
-		{
-			APIVersion: ownerGVK.GroupVersion().String(),
-			Kind:       ownerGVK.Kind,
-			Name:       ownerName,
-			UID:        types.UID(ownerName),
-			Controller: ptr.To(true),
-		},
-	}
+	testing.AppendOwnerReference(&j.Job, ownerGVK, ownerName, ownerName, ptr.To(true), ptr.To(true))
 	return j
 }
 
diff --git a/pkg/util/testingjobs/jobset/wrappers.go b/pkg/util/testingjobs/jobset/wrappers.go
index a6308a1d3..4a167d911 100644
--- a/pkg/util/testingjobs/jobset/wrappers.go
+++ b/pkg/util/testingjobs/jobset/wrappers.go
@@ -206,6 +206,6 @@ func (j *JobSetWrapper) ManagedBy(c string) *JobSetWrapper {
 
 // OwnerReference adds a ownerReference to the default container.
 func (j *JobSetWrapper) OwnerReference(ownerName string, ownerGVK schema.GroupVersionKind) *JobSetWrapper {
-	testing.AppendOwnerReference(j, ownerGVK, ownerName, ownerName, ptr.To(true), nil)
+	testing.AppendOwnerReference(j, ownerGVK, ownerName, ownerName, ptr.To(true), ptr.To(true))
 	return j
 }
diff --git a/pkg/util/testingjobs/leaderworkerset/wrappers.go b/pkg/util/testingjobs/leaderworkerset/wrappers.go
index cc0b620d2..d27730ad4 100644
--- a/pkg/util/testingjobs/leaderworkerset/wrappers.go
+++ b/pkg/util/testingjobs/leaderworkerset/wrappers.go
@@ -97,11 +97,6 @@ func (w *LeaderWorkerSetWrapper) UID(uid string) *LeaderWorkerSetWrapper {
 	return w
 }
 
-func (w *LeaderWorkerSetWrapper) WithOwnerReference(ownerReference metav1.OwnerReference) *LeaderWorkerSetWrapper {
-	w.OwnerReferences = append(w.OwnerReferences, ownerReference)
-	return w
-}
-
 func (w *LeaderWorkerSetWrapper) StartupPolicy(startupPolicyType leaderworkersetv1.StartupPolicyType) *LeaderWorkerSetWrapper {
 	w.Spec.StartupPolicy = startupPolicyType
 	return w
diff --git a/pkg/util/testingjobs/mpijob/wrappers_mpijob.go b/pkg/util/testingjobs/mpijob/wrappers_mpijob.go
index c1fc6a826..567b1339a 100644
--- a/pkg/util/testingjobs/mpijob/wrappers_mpijob.go
+++ b/pkg/util/testingjobs/mpijob/wrappers_mpijob.go
@@ -26,6 +26,7 @@ import (
 	"k8s.io/utils/ptr"
 
 	"sigs.k8s.io/kueue/pkg/controller/constants"
+	"sigs.k8s.io/kueue/pkg/util/testing"
 )
 
 // MPIJobWrapper wraps a Job.
@@ -203,13 +204,7 @@ func (j *MPIJobWrapper) UID(uid string) *MPIJobWrapper {
 
 // OwnerReference adds a ownerReference to the default container.
 func (j *MPIJobWrapper) OwnerReference(ownerName string, ownerGVK schema.GroupVersionKind) *MPIJobWrapper {
-	j.ObjectMeta.OwnerReferences = append(j.ObjectMeta.OwnerReferences, metav1.OwnerReference{
-		APIVersion: ownerGVK.GroupVersion().String(),
-		Kind:       ownerGVK.Kind,
-		Name:       ownerName,
-		UID:        types.UID(ownerName),
-		Controller: ptr.To(true),
-	})
+	testing.AppendOwnerReference(&j.MPIJob, ownerGVK, ownerName, ownerName, ptr.To(true), ptr.To(true))
 	return j
 }
 
diff --git a/pkg/util/testingjobs/pod/wrappers.go b/pkg/util/testingjobs/pod/wrappers.go
index eec5cbbfa..ee1d36d7f 100644
--- a/pkg/util/testingjobs/pod/wrappers.go
+++ b/pkg/util/testingjobs/pod/wrappers.go
@@ -32,6 +32,7 @@ import (
 	"sigs.k8s.io/kueue/pkg/constants"
 	controllerconsts "sigs.k8s.io/kueue/pkg/controller/constants"
 	podconstants "sigs.k8s.io/kueue/pkg/controller/jobs/pod/constants"
+	"sigs.k8s.io/kueue/pkg/util/testing"
 )
 
 // PodWrapper wraps a Pod.
@@ -255,17 +256,7 @@ func (p *PodWrapper) Limit(r corev1.ResourceName, v string) *PodWrapper {
 
 // OwnerReference adds a ownerReference to the default container.
 func (p *PodWrapper) OwnerReference(ownerName string, ownerGVK schema.GroupVersionKind) *PodWrapper {
-	p.ObjectMeta.OwnerReferences = append(
-		p.ObjectMeta.OwnerReferences,
-		metav1.OwnerReference{
-			APIVersion: ownerGVK.GroupVersion().String(),
-			Kind:       ownerGVK.Kind,
-			Name:       ownerName,
-			UID:        types.UID(ownerName),
-			Controller: ptr.To(true),
-		},
-	)
-
+	testing.AppendOwnerReference(&p.Pod, ownerGVK, ownerName, ownerName, ptr.To(true), ptr.To(true))
 	return p
 }
 
diff --git a/pkg/workload/workload_test.go b/pkg/workload/workload_test.go
index b9684d898..41a32545a 100644
--- a/pkg/workload/workload_test.go
+++ b/pkg/workload/workload_test.go
@@ -34,7 +34,7 @@ import (
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/resources"
-	utilac "sigs.k8s.io/kueue/pkg/util/admissioncheck"
+	"sigs.k8s.io/kueue/pkg/util/admissioncheck"
 	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 )
 
@@ -827,7 +827,7 @@ func TestAdmissionCheckStrategy(t *testing.T) {
 	cases := map[string]struct {
 		cq                  *kueue.ClusterQueue
 		wl                  *kueue.Workload
-		wantAdmissionChecks sets.Set[string]
+		wantAdmissionChecks sets.Set[kueue.AdmissionCheckReference]
 	}{
 		"AdmissionCheckStrategy with a flavor": {
 			wl: utiltesting.MakeWorkload("wl", "ns").
@@ -836,7 +836,7 @@ func TestAdmissionCheckStrategy(t *testing.T) {
 			cq: utiltesting.MakeClusterQueue("cq").
 				AdmissionCheckStrategy(*utiltesting.MakeAdmissionCheckStrategyRule("ac1", "flavor1").Obj()).
 				Obj(),
-			wantAdmissionChecks: sets.New("ac1"),
+			wantAdmissionChecks: sets.New[kueue.AdmissionCheckReference]("ac1"),
 		},
 		"AdmissionCheckStrategy with an unmatched flavor": {
 			wl: utiltesting.MakeWorkload("wl", "ns").
@@ -854,7 +854,7 @@ func TestAdmissionCheckStrategy(t *testing.T) {
 			cq: utiltesting.MakeClusterQueue("cq").
 				AdmissionCheckStrategy(*utiltesting.MakeAdmissionCheckStrategyRule("ac1").Obj()).
 				Obj(),
-			wantAdmissionChecks: sets.New("ac1"),
+			wantAdmissionChecks: sets.New[kueue.AdmissionCheckReference]("ac1"),
 		},
 		"Two AdmissionCheckStrategies, one with flavor, one without flavor": {
 			wl: utiltesting.MakeWorkload("wl", "ns").
@@ -865,7 +865,7 @@ func TestAdmissionCheckStrategy(t *testing.T) {
 					*utiltesting.MakeAdmissionCheckStrategyRule("ac1", "flavor1").Obj(),
 					*utiltesting.MakeAdmissionCheckStrategyRule("ac2").Obj()).
 				Obj(),
-			wantAdmissionChecks: sets.New("ac1", "ac2"),
+			wantAdmissionChecks: sets.New[kueue.AdmissionCheckReference]("ac1", "ac2"),
 		},
 		"Workload has no QuotaReserved": {
 			wl: utiltesting.MakeWorkload("wl", "ns").
@@ -881,7 +881,7 @@ func TestAdmissionCheckStrategy(t *testing.T) {
 	for name, tc := range cases {
 		t.Run(name, func(t *testing.T) {
 			_, log := utiltesting.ContextWithLog(t)
-			gotAdmissionChecks := AdmissionChecksForWorkload(log, tc.wl, utilac.NewAdmissionChecks(tc.cq))
+			gotAdmissionChecks := AdmissionChecksForWorkload(log, tc.wl, admissioncheck.NewAdmissionChecks(tc.cq))
 
 			if diff := cmp.Diff(tc.wantAdmissionChecks, gotAdmissionChecks); diff != "" {
 				t.Errorf("Unexpected AdmissionChecks, (want-/got+):\n%s", diff)
diff --git a/test/e2e/certmanager/suite_test.go b/test/e2e/certmanager/suite_test.go
index 4f8a5fc4e..e2513ad4a 100644
--- a/test/e2e/certmanager/suite_test.go
+++ b/test/e2e/certmanager/suite_test.go
@@ -60,7 +60,10 @@ var _ = ginkgo.BeforeSuite(func() {
 
 	waitForAvailableStart := time.Now()
 	util.WaitForKueueAvailability(ctx, k8sClient)
-	ginkgo.GinkgoLogr.Info("Kueue operator is available in the cluster", "waitingTime", time.Since(waitForAvailableStart))
+	ginkgo.GinkgoLogr.Info(
+		"Kueue and all required operators are available in the cluster",
+		"waitingTime", time.Since(waitForAvailableStart),
+	)
 	defaultKueueCfg = util.GetKueueConfiguration(ctx, k8sClient)
 })
 
diff --git a/test/e2e/config/default/kustomization.yaml b/test/e2e/config/default/kustomization.yaml
index 11a455055..dcf86970a 100644
--- a/test/e2e/config/default/kustomization.yaml
+++ b/test/e2e/config/default/kustomization.yaml
@@ -3,7 +3,6 @@ kind: Kustomization
 
 resources:
 - ../../../../config/dev
-- ../../../../config/visibility-apf
 
 replicas:
 - name: kueue-controller-manager
diff --git a/test/e2e/customconfigs/managejobswithoutqueuename_test.go b/test/e2e/customconfigs/managejobswithoutqueuename_test.go
index 502d92915..ca8ad7206 100644
--- a/test/e2e/customconfigs/managejobswithoutqueuename_test.go
+++ b/test/e2e/customconfigs/managejobswithoutqueuename_test.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package queuename
+package customconfigse2e
 
 import (
 	"github.com/onsi/ginkgo/v2"
@@ -650,6 +650,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 					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))
+					util.MustHaveOwnerReference(g, createdWorkloads.Items[0].OwnerReferences, lws, k8sClient.Scheme())
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -673,6 +674,21 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 						g.Expect(pod.Status.Phase).Should(gomega.Equal(corev1.PodRunning))
 					}
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+
+				ginkgo.By("Delete the LeaderWorkerSet", func() {
+					util.ExpectObjectToBeDeleted(ctx, k8sClient, lws, true)
+				})
+
+				ginkgo.By("Check workload is deleted", func() {
+					wlLookupKey := types.NamespacedName{
+						Name:      leaderworkerset.GetWorkloadName(lws.UID, lws.Name, "0"),
+						Namespace: ns.Name,
+					}
+					createdWorkload := &kueue.Workload{}
+					gomega.Eventually(func(g gomega.Gomega) {
+						g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(testing.BeNotFoundError())
+					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+				})
 			})
 		})
 
@@ -695,6 +711,7 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 					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))
+					util.MustHaveOwnerReference(g, createdWorkloads.Items[0].OwnerReferences, lws, k8sClient.Scheme())
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -719,6 +736,21 @@ var _ = ginkgo.Describe("ManageJobsWithoutQueueName", ginkgo.Ordered, func() {
 					}
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
+
+			ginkgo.By("Delete the LeaderWorkerSet", func() {
+				util.ExpectObjectToBeDeleted(ctx, k8sClient, lws, true)
+			})
+
+			ginkgo.By("Check workload is deleted", func() {
+				wlLookupKey := types.NamespacedName{
+					Name:      leaderworkerset.GetWorkloadName(lws.UID, lws.Name, "0"),
+					Namespace: ns.Name,
+				}
+				createdWorkload := &kueue.Workload{}
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(testing.BeNotFoundError())
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
 		})
 	})
 })
diff --git a/test/e2e/customconfigs/suite_test.go b/test/e2e/customconfigs/suite_test.go
index ed1fd2406..3dc72c2c0 100644
--- a/test/e2e/customconfigs/suite_test.go
+++ b/test/e2e/customconfigs/suite_test.go
@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
 limitations under the License.
 */
 
-package queuename
+package customconfigse2e
 
 import (
 	"context"
@@ -25,6 +25,7 @@ import (
 
 	"github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega"
+	"k8s.io/client-go/rest"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
 	"sigs.k8s.io/kueue/apis/config/v1beta1"
@@ -33,6 +34,8 @@ import (
 
 var (
 	k8sClient       client.WithWatch
+	cfg             *rest.Config
+	restClient      *rest.RESTClient
 	ctx             context.Context
 	defaultKueueCfg *v1beta1.Configuration
 )
@@ -51,14 +54,19 @@ func TestAPIs(t *testing.T) {
 var _ = ginkgo.BeforeSuite(func() {
 	util.SetupLogger()
 
-	k8sClient, _ = util.CreateClientUsingCluster("")
+	k8sClient, cfg = util.CreateClientUsingCluster("")
+	restClient = util.CreateRestClient(cfg)
 	ctx = ginkgo.GinkgoT().Context()
 
 	waitForAvailableStart := time.Now()
 	util.WaitForKueueAvailability(ctx, k8sClient)
 	util.WaitForJobSetAvailability(ctx, k8sClient)
 	util.WaitForAppWrapperAvailability(ctx, k8sClient)
-	ginkgo.GinkgoLogr.Info("Kueue, JobSet and AppWrapper operators are available in the cluster", "waitingTime", time.Since(waitForAvailableStart))
+	util.WaitForLeaderWorkerSetAvailability(ctx, k8sClient)
+	ginkgo.GinkgoLogr.Info(
+		"Kueue and all required operators are available in the cluster",
+		"waitingTime", time.Since(waitForAvailableStart),
+	)
 	defaultKueueCfg = util.GetKueueConfiguration(ctx, k8sClient)
 })
 
diff --git a/test/e2e/customconfigs/waitforpodsready_test.go b/test/e2e/customconfigs/waitforpodsready_test.go
new file mode 100644
index 000000000..ed76a853b
--- /dev/null
+++ b/test/e2e/customconfigs/waitforpodsready_test.go
@@ -0,0 +1,287 @@
+/*
+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 customconfigse2e
+
+import (
+	"github.com/onsi/ginkgo/v2"
+	"github.com/onsi/gomega"
+	batchv1 "k8s.io/api/batch/v1"
+	corev1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	"k8s.io/utils/ptr"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+
+	configapi "sigs.k8s.io/kueue/apis/config/v1beta1"
+	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
+	workloadjob "sigs.k8s.io/kueue/pkg/controller/jobs/job"
+	"sigs.k8s.io/kueue/pkg/util/testing"
+	testingjob "sigs.k8s.io/kueue/pkg/util/testingjobs/job"
+	"sigs.k8s.io/kueue/pkg/workload"
+	"sigs.k8s.io/kueue/test/util"
+)
+
+var _ = ginkgo.Describe("WaitForPodsReady Job Controller E2E", func() {
+	var (
+		ns    *corev1.Namespace
+		rf    *kueue.ResourceFlavor
+		cq    *kueue.ClusterQueue
+		lq    *kueue.LocalQueue
+		job   *batchv1.Job
+		wl    kueue.Workload
+		wlKey types.NamespacedName
+	)
+
+	ginkgo.BeforeEach(func() {
+		ns = util.CreateNamespaceFromPrefixWithLog(ctx, k8sClient, "wfpr-")
+
+		rf = testing.MakeResourceFlavor("default").Obj()
+		gomega.Expect(k8sClient.Create(ctx, rf)).Should(gomega.Succeed())
+
+		cq = testing.MakeClusterQueue("cq").
+			ResourceGroup(*testing.MakeFlavorQuotas(rf.Name).Resource(corev1.ResourceCPU, "10").Obj()).
+			Obj()
+		gomega.Expect(k8sClient.Create(ctx, cq)).Should(gomega.Succeed())
+
+		lq = testing.MakeLocalQueue("lq", ns.Name).ClusterQueue(cq.Name).Obj()
+		gomega.Expect(k8sClient.Create(ctx, lq)).Should(gomega.Succeed())
+	})
+
+	ginkgo.AfterEach(func() {
+		gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
+		util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
+		util.ExpectObjectToBeDeleted(ctx, k8sClient, rf, true)
+	})
+
+	ginkgo.When("WaitForPodsReady has a tiny Timeout and no RecoveryTimeout", func() {
+		ginkgo.BeforeEach(func() {
+			updateKueueConfiguration(func(cfg *configapi.Configuration) {
+				cfg.WaitForPodsReady = &configapi.WaitForPodsReady{
+					Enable:          true,
+					BlockAdmission:  ptr.To(true),
+					Timeout:         &metav1.Duration{Duration: util.TinyTimeout},
+					RecoveryTimeout: nil,
+					RequeuingStrategy: &configapi.RequeuingStrategy{
+						Timestamp:          ptr.To(configapi.EvictionTimestamp),
+						BackoffBaseSeconds: ptr.To(int32(10)),
+						BackoffLimitCount:  ptr.To(int32(1)),
+					},
+				}
+			})
+		})
+
+		ginkgo.It("should evict and requeue workload when pods readiness timeout is surpassed", func() {
+			ginkgo.By("creating a suspended job so its pods never report Ready", func() {
+				job = testingjob.MakeJob("job-timeout", ns.Name).
+					Queue(lq.Name).
+					Request(corev1.ResourceCPU, "2").
+					Parallelism(1).
+					Obj()
+				gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
+			})
+
+			wlKey = types.NamespacedName{
+				Name:      workloadjob.GetWorkloadNameForJob(job.Name, job.UID),
+				Namespace: ns.Name,
+			}
+
+			ginkgo.By("waiting for the workload to be created and verifying it is not admitted", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, wlKey, &wl)).Should(gomega.Succeed())
+
+					g.Expect(wl.Status.Admission).To(gomega.BeNil())
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			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(
+						workload.HasConditionWithTypeAndReason(&wl, &metav1.Condition{
+							Type:   kueue.WorkloadPodsReady,
+							Status: metav1.ConditionFalse,
+							Reason: kueue.WorkloadWaitForStart,
+						}),
+					).To(gomega.BeTrue())
+
+					g.Expect(
+						workload.HasConditionWithTypeAndReason(&wl, &metav1.Condition{
+							Type:   kueue.WorkloadEvicted,
+							Status: metav1.ConditionTrue,
+							Reason: kueue.WorkloadEvictedByPodsReadyTimeout,
+						}),
+					).To(gomega.BeTrue())
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("verifying that the job is suspended", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(job), job)).Should(gomega.Succeed())
+					g.Expect(ptr.Deref(job.Spec.Suspend, false)).To(gomega.BeTrue())
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("verifying that the workload is requeued", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					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)))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("verifying that the workload is deactivated after the second eviction", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, wlKey, &wl)).Should(gomega.Succeed())
+					g.Expect(ptr.Deref(wl.Spec.Active, true)).Should(gomega.BeFalse())
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
+
+	ginkgo.When("WaitForPodsReady has default Timeout and a tiny RecoveryTimeout", func() {
+		ginkgo.BeforeEach(func() {
+			updateKueueConfiguration(func(cfg *configapi.Configuration) {
+				cfg.WaitForPodsReady = &configapi.WaitForPodsReady{
+					Enable:          true,
+					BlockAdmission:  ptr.To(true),
+					RecoveryTimeout: &metav1.Duration{Duration: util.TinyTimeout},
+					RequeuingStrategy: &configapi.RequeuingStrategy{
+						Timestamp:          ptr.To(configapi.EvictionTimestamp),
+						BackoffBaseSeconds: ptr.To(int32(1)),
+						BackoffLimitCount:  ptr.To(int32(1)),
+					},
+				}
+			})
+		})
+
+		ginkgo.It("should evict and requeue workload when pod failure causes recovery timeout", func() {
+			ginkgo.By("creating a job", func() {
+				job = testingjob.MakeJob("job-recovery-timeout", ns.Name).
+					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+					Queue(lq.Name).
+					Request(corev1.ResourceCPU, "2").
+					Parallelism(1).
+					BackoffLimitPerIndex(2).
+					CompletionMode(batchv1.IndexedCompletion).
+					Completions(1).
+					Obj()
+
+				gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
+			})
+
+			wlKey = types.NamespacedName{
+				Name:      workloadjob.GetWorkloadNameForJob(job.Name, job.UID),
+				Namespace: ns.Name,
+			}
+
+			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))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("simulating pod failure", func() {
+				util.WaitForActivePodsAndTerminate(ctx, k8sClient, restClient, cfg, ns.Name, 1, 1)
+			})
+
+			ginkgo.By("verifying that the workload is requeued", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					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(
+						workload.HasConditionWithTypeAndReason(&wl, &metav1.Condition{
+							Type:   kueue.WorkloadPodsReady,
+							Status: metav1.ConditionTrue,
+							Reason: kueue.WorkloadStarted,
+						}),
+					).To(gomega.BeTrue())
+
+					g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusFalse(kueue.WorkloadEvicted))
+
+					g.Expect(wl.Status.Conditions).To(testing.HaveConditionStatusTrue(kueue.WorkloadRequeued))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
+
+	ginkgo.When("WaitForPodsReady has default Timeout and a long RecoveryTimeout", func() {
+		ginkgo.BeforeEach(func() {
+			updateKueueConfiguration(func(cfg *configapi.Configuration) {
+				cfg.WaitForPodsReady = &configapi.WaitForPodsReady{
+					Enable:          true,
+					BlockAdmission:  ptr.To(true),
+					RecoveryTimeout: &metav1.Duration{Duration: util.LongTimeout},
+					RequeuingStrategy: &configapi.RequeuingStrategy{
+						Timestamp:          ptr.To(configapi.EvictionTimestamp),
+						BackoffBaseSeconds: ptr.To(int32(1)),
+						BackoffLimitCount:  ptr.To(int32(1)),
+					},
+				}
+			})
+		})
+
+		ginkgo.It("should continue running workload if pod recovers before recoveryTimeout", func() {
+			ginkgo.By("creating a job", func() {
+				job = testingjob.MakeJob("job-recovery-timeout", ns.Name).
+					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+					Queue(lq.Name).
+					Request(corev1.ResourceCPU, "2").
+					Parallelism(1).
+					BackoffLimitPerIndex(2).
+					CompletionMode(batchv1.IndexedCompletion).
+					Completions(1).
+					Obj()
+
+				gomega.Expect(k8sClient.Create(ctx, job)).Should(gomega.Succeed())
+			})
+
+			wlKey = types.NamespacedName{
+				Name:      workloadjob.GetWorkloadNameForJob(job.Name, job.UID),
+				Namespace: ns.Name,
+			}
+
+			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))
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("simulating pod failure", func() {
+				util.WaitForActivePodsAndTerminate(ctx, k8sClient, restClient, cfg, ns.Name, 1, 1)
+			})
+
+			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(
+						workload.HasConditionWithTypeAndReason(&wl, &metav1.Condition{
+							Type:   kueue.WorkloadPodsReady,
+							Status: metav1.ConditionTrue,
+							Reason: kueue.WorkloadRecovered,
+						}),
+					).To(gomega.BeTrue())
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
+})
diff --git a/test/e2e/multikueue/e2e_test.go b/test/e2e/multikueue/e2e_test.go
index 6be400f1c..07976a037 100644
--- a/test/e2e/multikueue/e2e_test.go
+++ b/test/e2e/multikueue/e2e_test.go
@@ -125,7 +125,7 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 					Resource(corev1.ResourceMemory, "2G").
 					Obj(),
 			).
-			AdmissionChecks(multiKueueAc.Name).
+			AdmissionChecks(kueue.AdmissionCheckReference(multiKueueAc.Name)).
 			Obj()
 		util.MustCreate(ctx, k8sManagerClient, managerCq)
 
@@ -213,8 +213,8 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 			ginkgo.By("Waiting to be admitted in worker2", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, createdLeaderWorkload)).To(gomega.Succeed())
-					g.Expect(workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, multiKueueAc.Name)).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
-						Name:    multiKueueAc.Name,
+					g.Expect(workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAc.Name))).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
+						Name:    kueue.AdmissionCheckReference(multiKueueAc.Name),
 						State:   kueue.CheckStatePending,
 						Message: `The workload got reservation on "worker2"`,
 					}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime")))
@@ -407,8 +407,8 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 			ginkgo.By("Waiting to be admitted in worker2", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, createdLeaderWorkload)).To(gomega.Succeed())
-					g.Expect(workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, multiKueueAc.Name)).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
-						Name:    multiKueueAc.Name,
+					g.Expect(workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAc.Name))).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
+						Name:    kueue.AdmissionCheckReference(multiKueueAc.Name),
 						State:   kueue.CheckStatePending,
 						Message: `The workload got reservation on "worker2"`,
 					}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime")))
@@ -463,8 +463,8 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 			ginkgo.By("Waiting to be admitted in worker2, and the manager's job unsuspended", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, createdLeaderWorkload)).To(gomega.Succeed())
-					g.Expect(workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, multiKueueAc.Name)).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
-						Name:    multiKueueAc.Name,
+					g.Expect(workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAc.Name))).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
+						Name:    kueue.AdmissionCheckReference(multiKueueAc.Name),
 						State:   kueue.CheckStateReady,
 						Message: `The workload got reservation on "worker2"`,
 					}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime")))
@@ -553,8 +553,8 @@ var _ = ginkgo.Describe("MultiKueue", func() {
 			ginkgo.By("Waiting to be admitted in worker1 and manager", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sManagerClient.Get(ctx, wlLookupKey, createdLeaderWorkload)).To(gomega.Succeed())
-					g.Expect(workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, multiKueueAc.Name)).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
-						Name:    multiKueueAc.Name,
+					g.Expect(workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAc.Name))).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
+						Name:    kueue.AdmissionCheckReference(multiKueueAc.Name),
 						State:   kueue.CheckStateReady,
 						Message: `The workload got reservation on "worker1"`,
 					}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime")))
@@ -983,8 +983,8 @@ func waitForJobAdmitted(wlLookupKey types.NamespacedName, acName, workerName str
 			Reason:  "Admitted",
 			Message: "The workload is admitted",
 		}, util.IgnoreConditionTimestampsAndObservedGeneration))
-		g.Expect(workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, acName)).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
-			Name:    acName,
+		g.Expect(workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(acName))).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
+			Name:    kueue.AdmissionCheckReference(acName),
 			State:   kueue.CheckStateReady,
 			Message: fmt.Sprintf(`The workload got reservation on "%s"`, workerName),
 		}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime")))
@@ -1015,7 +1015,7 @@ func ensurePodWorkloadsRunning(deployment *appsv1.Deployment, managerNs corev1.N
 		gomega.Expect(k8sManagerClient.Get(ctx, wlLookupKey, createdLeaderWorkload)).To(gomega.Succeed())
 
 		// By checking the assigned cluster we can discern which client to use
-		admissionCheckMessage := workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, multiKueueAc.Name).Message
+		admissionCheckMessage := workload.FindAdmissionCheck(createdLeaderWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAc.Name)).Message
 		workerCluster := kubernetesClients[GetMultiKueueClusterNameFromAdmissionCheckMessage(admissionCheckMessage)]
 
 		// Worker pods should be in "Running" phase
diff --git a/test/e2e/multikueue/suite_test.go b/test/e2e/multikueue/suite_test.go
index 91a0dbd1c..4b73bb2b6 100644
--- a/test/e2e/multikueue/suite_test.go
+++ b/test/e2e/multikueue/suite_test.go
@@ -301,7 +301,10 @@ var _ = ginkgo.BeforeSuite(func() {
 	util.WaitForKubeRayOperatorAvailability(ctx, k8sWorker1Client)
 	util.WaitForKubeRayOperatorAvailability(ctx, k8sWorker2Client)
 
-	ginkgo.GinkgoLogr.Info("Kueue and all integration operators are available in all the clusters", "waitingTime", time.Since(waitForAvailableStart))
+	ginkgo.GinkgoLogr.Info(
+		"Kueue and all required operators are available in all the clusters",
+		"waitingTime", time.Since(waitForAvailableStart),
+	)
 	discoveryClient, err := discovery.NewDiscoveryClientForConfig(managerCfg)
 	gomega.Expect(err).NotTo(gomega.HaveOccurred())
 	managerK8SVersion, err = kubeversion.FetchServerVersion(discoveryClient)
diff --git a/test/e2e/singlecluster/e2e_test.go b/test/e2e/singlecluster/e2e_test.go
index 00289dbfd..6a8c620ed 100644
--- a/test/e2e/singlecluster/e2e_test.go
+++ b/test/e2e/singlecluster/e2e_test.go
@@ -17,7 +17,6 @@ limitations under the License.
 package e2e
 
 import (
-	"github.com/google/go-cmp/cmp/cmpopts"
 	"github.com/onsi/ginkgo/v2"
 	"github.com/onsi/gomega"
 	batchv1 "k8s.io/api/batch/v1"
@@ -170,11 +169,7 @@ var _ = ginkgo.Describe("Kueue", func() {
 					g.Expect(k8sClient.Get(ctx, jobLookupKey, createdJob)).To(gomega.Succeed())
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
 					g.Expect(wl.Spec.PodSets[0].Template.Spec.Containers).To(gomega.BeComparableTo(createdJob.Spec.Template.Spec.Containers), "Check the way the job and workload is created")
-					g.Expect(createdWorkload.OwnerReferences).To(gomega.ContainElement(
-						gomega.BeComparableTo(metav1.OwnerReference{
-							Name: sampleJob.Name,
-							UID:  sampleJob.UID,
-						}, cmpopts.IgnoreFields(metav1.OwnerReference{}, "APIVersion", "Kind", "Controller", "BlockOwnerDeletion"))))
+					util.MustHaveOwnerReference(g, createdWorkload.OwnerReferences, sampleJob, k8sClient.Scheme())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -369,9 +364,9 @@ var _ = ginkgo.Describe("Kueue", func() {
 			ginkgo.By("verify the check is added to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
-					g.Expect(slices.ToMap(createdWorkload.Status.AdmissionChecks, func(i int) (string, string) {
+					g.Expect(slices.ToMap(createdWorkload.Status.AdmissionChecks, func(i int) (kueue.AdmissionCheckReference, string) {
 						return createdWorkload.Status.AdmissionChecks[i].Name, ""
-					})).Should(gomega.BeComparableTo(map[string]string{"check1": ""}))
+					})).Should(gomega.BeComparableTo(map[kueue.AdmissionCheckReference]string{"check1": ""}))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -423,9 +418,9 @@ var _ = ginkgo.Describe("Kueue", func() {
 			ginkgo.By("verify the check is added to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).Should(gomega.Succeed())
-					g.Expect(slices.ToMap(createdWorkload.Status.AdmissionChecks, func(i int) (string, string) {
+					g.Expect(slices.ToMap(createdWorkload.Status.AdmissionChecks, func(i int) (kueue.AdmissionCheckReference, string) {
 						return createdWorkload.Status.AdmissionChecks[i].Name, ""
-					})).Should(gomega.BeComparableTo(map[string]string{"check1": ""}))
+					})).Should(gomega.BeComparableTo(map[kueue.AdmissionCheckReference]string{"check1": ""}))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
diff --git a/test/e2e/singlecluster/leaderworkerset_test.go b/test/e2e/singlecluster/leaderworkerset_test.go
index dc02ade9c..866fe2d7d 100644
--- a/test/e2e/singlecluster/leaderworkerset_test.go
+++ b/test/e2e/singlecluster/leaderworkerset_test.go
@@ -30,6 +30,7 @@ import (
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/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"
 	leaderworkersettesting "sigs.k8s.io/kueue/pkg/util/testingjobs/leaderworkerset"
 	"sigs.k8s.io/kueue/test/util"
@@ -449,6 +450,109 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 			ginkgo.Entry("LeaderReadyStartupPolicy", leaderworkersetv1.LeaderReadyStartupPolicy),
 		)
 
+		ginkgo.DescribeTable("should allow to scale up, scale down fast",
+			func(startupPolicyType leaderworkersetv1.StartupPolicyType) {
+				lws := leaderworkersettesting.MakeLeaderWorkerSet("lws", ns.Name).
+					Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+					Size(3).
+					Replicas(1).
+					RequestAndLimit(corev1.ResourceCPU, "200m").
+					TerminationGracePeriod(1).
+					Queue(lq.Name).
+					StartupPolicy(startupPolicyType).
+					Obj()
+
+				ginkgo.By("Create a LeaderWorkerSet", func() {
+					gomega.Expect(k8sClient.Create(ctx, lws)).To(gomega.Succeed())
+				})
+
+				createdLeaderWorkerSet := &leaderworkersetv1.LeaderWorkerSet{}
+
+				ginkgo.By("Waiting for replicas is ready", 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(gomega.ContainElement(
+							gomega.BeComparableTo(metav1.Condition{
+								Type:   "Available",
+								Status: metav1.ConditionTrue,
+								Reason: "AllGroupsReady",
+							}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage)),
+						)
+					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+				})
+
+				createdWorkload1 := &kueue.Workload{}
+				wlLookupKey1 := types.NamespacedName{Name: leaderworkerset.GetWorkloadName(lws.UID, lws.Name, "0"), Namespace: ns.Name}
+				ginkgo.By("Check workload is created", func() {
+					gomega.Expect(k8sClient.Get(ctx, wlLookupKey1, createdWorkload1)).To(gomega.Succeed())
+				})
+
+				ginkgo.By("Scale up LeaderWorkerSet", func() {
+					gomega.Eventually(func(g gomega.Gomega) {
+						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
+						createdLeaderWorkerSet.Spec.Replicas = ptr.To[int32](2)
+						g.Expect(k8sClient.Update(ctx, createdLeaderWorkerSet)).To(gomega.Succeed())
+					}, util.Timeout, util.Interval).Should(gomega.Succeed())
+				})
+
+				ginkgo.By("Scale down LeaderWorkerSet", func() {
+					gomega.Eventually(func(g gomega.Gomega) {
+						g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lws), createdLeaderWorkerSet)).To(gomega.Succeed())
+						createdLeaderWorkerSet.Spec.Replicas = ptr.To[int32](1)
+						g.Expect(k8sClient.Update(ctx, createdLeaderWorkerSet)).To(gomega.Succeed())
+					}, util.Timeout, util.Interval).Should(gomega.Succeed())
+				})
+
+				ginkgo.By("Waiting for replicas is ready", 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(gomega.ContainElement(
+							gomega.BeComparableTo(metav1.Condition{
+								Type:   "Available",
+								Status: metav1.ConditionTrue,
+								Reason: "AllGroupsReady",
+							}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage)),
+						)
+					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+				})
+
+				ginkgo.By("Check workload for group 1 is still exist", func() {
+					gomega.Expect(k8sClient.Get(ctx, wlLookupKey1, createdWorkload1)).To(gomega.Succeed())
+				})
+
+				createdWorkload2 := &kueue.Workload{}
+				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())
+					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+				})
+
+				ginkgo.By("Delete the LeaderWorkerSet", func() {
+					util.ExpectObjectToBeDeleted(ctx, k8sClient, lws, true)
+				})
+
+				ginkgo.By("Check pods are deleted", func() {
+					pods := &corev1.PodList{}
+					gomega.Eventually(func(g gomega.Gomega) {
+						g.Expect(k8sClient.List(ctx, pods, client.MatchingLabels{
+							leaderworkersetv1.SetNameLabelKey: lws.Name,
+						}, client.InNamespace(lws.Namespace))).Should(gomega.Succeed())
+						g.Expect(pods.Items).To(gomega.BeEmpty())
+					}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+				})
+
+				ginkgo.By("Check workloads are deleted", func() {
+					util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sClient, createdWorkload1, false, util.LongTimeout)
+					util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sClient, createdWorkload2, false, util.LongTimeout)
+				})
+			},
+			ginkgo.Entry("LeaderCreatedStartupPolicy", leaderworkersetv1.LeaderCreatedStartupPolicy),
+			ginkgo.Entry("LeaderReadyStartupPolicy", leaderworkersetv1.LeaderReadyStartupPolicy),
+		)
+
 		ginkgo.DescribeTable("should admit group with multiple leaders and workers that fits and have different resource needs",
 			func(startupPolicyType leaderworkersetv1.StartupPolicyType) {
 				lws := leaderworkersettesting.MakeLeaderWorkerSet("lws", ns.Name).
@@ -789,6 +893,155 @@ var _ = ginkgo.Describe("LeaderWorkerSet integration", func() {
 					g.Expect(createdHighPriorityWl.Spec.PriorityClassName).To(gomega.Equal(highPriorityLWS.Name))
 				}, 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))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+		})
+	})
+
+	ginkgo.When("Workload deactivated", func() {
+		ginkgo.It("shouldn't delete deactivated Workload", func() {
+			lws := leaderworkersettesting.MakeLeaderWorkerSet("lws", ns.Name).
+				Image(util.E2eTestAgnHostImage, util.BehaviorWaitForDeletion).
+				Size(3).
+				Replicas(1).
+				RequestAndLimit(corev1.ResourceCPU, "200m").
+				TerminationGracePeriod(1).
+				Queue(lq.Name).
+				Obj()
+
+			ginkgo.By("Create a LeaderWorkerSet", func() {
+				gomega.Expect(k8sClient.Create(ctx, lws)).To(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for replicas is ready", func() {
+				createdLeaderWorkerSet := &leaderworkersetv1.LeaderWorkerSet{}
+
+				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(gomega.ContainElement(
+						gomega.BeComparableTo(metav1.Condition{
+							Type:   "Available",
+							Status: metav1.ConditionTrue,
+							Reason: "AllGroupsReady",
+						}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage)),
+					)
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			wlLookupKey := types.NamespacedName{
+				Name:      leaderworkerset.GetWorkloadName(lws.UID, lws.Name, "0"),
+				Namespace: ns.Name,
+			}
+			createdWorkload := &kueue.Workload{}
+			ginkgo.By("Check workload is created", func() {
+				gomega.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
+			})
+
+			createdWorkloadUID := createdWorkload.UID
+
+			ginkgo.By("Deactivate workload", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
+					createdWorkload.Spec.Active = ptr.To(false)
+					g.Expect(k8sClient.Update(ctx, createdWorkload)).To(gomega.Succeed())
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for replicas to not be ready", func() {
+				createdLeaderWorkerSet := &leaderworkersetv1.LeaderWorkerSet{}
+
+				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(gomega.ContainElement(
+						gomega.BeComparableTo(metav1.Condition{
+							Type:   "Available",
+							Status: metav1.ConditionFalse,
+							Reason: "AllGroupsReady",
+						}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage)),
+					)
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Check pods are gated", func() {
+				pods := &corev1.PodList{}
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.List(ctx, pods, client.MatchingLabels{
+						leaderworkersetv1.SetNameLabelKey: lws.Name,
+					}, client.InNamespace(lws.Namespace))).Should(gomega.Succeed())
+					g.Expect(pods.Items).To(gomega.HaveLen(3))
+					for _, pod := range pods.Items {
+						g.Expect(pod.Spec.SchedulingGates).To(gomega.ContainElement(corev1.PodSchedulingGate{
+							Name: podconstants.SchedulingGateName,
+						}))
+					}
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Check workload is deactivated", func() {
+				gomega.Consistently(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.Spec.Active).Should(gomega.Equal(ptr.To(false)))
+				}, util.ConsistentDuration, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Activate workload", func() {
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.Get(ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
+					createdWorkload.Spec.Active = ptr.To(true)
+					g.Expect(k8sClient.Update(ctx, createdWorkload)).To(gomega.Succeed())
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Waiting for replicas to be ready", func() {
+				createdLeaderWorkerSet := &leaderworkersetv1.LeaderWorkerSet{}
+
+				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(gomega.ContainElement(
+						gomega.BeComparableTo(metav1.Condition{
+							Type:   "Available",
+							Status: metav1.ConditionTrue,
+							Reason: "AllGroupsReady",
+						}, util.IgnoreConditionTimestampsAndObservedGeneration, util.IgnoreConditionMessage)),
+					)
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Check workload is admitted", 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))
+				}, util.Timeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Delete the LeaderWorkerSet", func() {
+				util.ExpectObjectToBeDeleted(ctx, k8sClient, lws, true)
+			})
+
+			ginkgo.By("Check pods are deleted", func() {
+				pods := &corev1.PodList{}
+				gomega.Eventually(func(g gomega.Gomega) {
+					g.Expect(k8sClient.List(ctx, pods, client.MatchingLabels{
+						leaderworkersetv1.SetNameLabelKey: lws.Name,
+					}, client.InNamespace(lws.Namespace))).Should(gomega.Succeed())
+					g.Expect(pods.Items).To(gomega.BeEmpty())
+				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Check workload is deleted", func() {
+				util.ExpectObjectToBeDeletedWithTimeout(ctx, k8sClient, createdWorkload, false, util.LongTimeout)
+			})
 		})
 	})
 })
diff --git a/test/e2e/singlecluster/metrics_test.go b/test/e2e/singlecluster/metrics_test.go
index 6dd0ddfa2..e38a30cd1 100644
--- a/test/e2e/singlecluster/metrics_test.go
+++ b/test/e2e/singlecluster/metrics_test.go
@@ -256,7 +256,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 						Resource(corev1.ResourceMemory, "1Gi").
 						Obj(),
 				).
-				AdmissionChecks(admissionCheck.Name).
+				AdmissionChecks(v1beta1.AdmissionCheckReference(admissionCheck.Name)).
 				Obj()
 			util.MustCreate(ctx, k8sClient, clusterQueue)
 
@@ -301,7 +301,7 @@ var _ = ginkgo.Describe("Metrics", func() {
 					g.Expect(k8sClient.Get(ctx, workloadKey, createdWorkload)).Should(gomega.Succeed())
 					patch := workload.BaseSSAWorkload(createdWorkload)
 					workload.SetAdmissionCheckState(&patch.Status.AdmissionChecks, v1beta1.AdmissionCheckState{
-						Name:  admissionCheck.Name,
+						Name:  v1beta1.AdmissionCheckReference(admissionCheck.Name),
 						State: v1beta1.CheckStateReady,
 					}, realClock)
 					g.Expect(k8sClient.Status().
diff --git a/test/e2e/singlecluster/suite_test.go b/test/e2e/singlecluster/suite_test.go
index 0beeb8b68..d905178e3 100644
--- a/test/e2e/singlecluster/suite_test.go
+++ b/test/e2e/singlecluster/suite_test.go
@@ -70,5 +70,8 @@ var _ = ginkgo.BeforeSuite(func() {
 	util.WaitForJobSetAvailability(ctx, k8sClient)
 	util.WaitForLeaderWorkerSetAvailability(ctx, k8sClient)
 	util.WaitForAppWrapperAvailability(ctx, k8sClient)
-	ginkgo.GinkgoLogr.Info("Kueue, JobSet, LeaderWorkerSet and AppWrapper operators are available in the cluster", "waitingTime", time.Since(waitForAvailableStart))
+	ginkgo.GinkgoLogr.Info(
+		"Kueue and all required operators are available in the cluster",
+		"waitingTime", time.Since(waitForAvailableStart),
+	)
 })
diff --git a/test/e2e/tas/leaderworkerset_test.go b/test/e2e/tas/leaderworkerset_test.go
index ae4d211ff..a9db74351 100644
--- a/test/e2e/tas/leaderworkerset_test.go
+++ b/test/e2e/tas/leaderworkerset_test.go
@@ -153,15 +153,24 @@ var _ = ginkgo.Describe("TopologyAwareScheduling for LeaderWorkerSet", func() {
 					index := fmt.Sprintf("%s/%s", pod.Labels[leaderworkersetv1.GroupIndexLabelKey], pod.Labels[leaderworkersetv1.WorkerIndexLabelKey])
 					gotAssignment[index] = pod.Spec.NodeName
 				}
-				wantAssignment := map[string]string{
-					"0/0": "kind-worker",
-					"0/1": "kind-worker2",
-					"0/2": "kind-worker3",
-					"1/0": "kind-worker5",
-					"1/1": "kind-worker6",
-					"1/2": "kind-worker7",
-				}
-				gomega.Expect(gotAssignment).Should(gomega.BeComparableTo(wantAssignment))
+				gomega.Expect(gotAssignment).Should(gomega.Or(
+					gomega.BeComparableTo(map[string]string{
+						"0/0": "kind-worker",
+						"0/1": "kind-worker2",
+						"0/2": "kind-worker3",
+						"1/0": "kind-worker5",
+						"1/1": "kind-worker6",
+						"1/2": "kind-worker7",
+					}),
+					gomega.BeComparableTo(map[string]string{
+						"1/0": "kind-worker",
+						"1/1": "kind-worker2",
+						"1/2": "kind-worker3",
+						"0/0": "kind-worker5",
+						"0/1": "kind-worker6",
+						"0/2": "kind-worker7",
+					}),
+				))
 			})
 		},
 		)
diff --git a/test/e2e/tas/suite_test.go b/test/e2e/tas/suite_test.go
index 50265cf6b..d818f206e 100644
--- a/test/e2e/tas/suite_test.go
+++ b/test/e2e/tas/suite_test.go
@@ -61,9 +61,10 @@ var _ = ginkgo.BeforeSuite(func() {
 	util.WaitForKubeFlowTrainingOperatorAvailability(ctx, k8sClient)
 	util.WaitForKubeFlowMPIOperatorAvailability(ctx, k8sClient)
 	util.WaitForAppWrapperAvailability(ctx, k8sClient)
+	util.WaitForLeaderWorkerSetAvailability(ctx, k8sClient)
 	util.WaitForKubeRayOperatorAvailability(ctx, k8sClient)
 	ginkgo.GinkgoLogr.Info(
-		"Kueue, JobSet, KubeFlow Training and KubeFlow MPI operators are available in the cluster",
+		"Kueue and all required operators are available in the cluster",
 		"waitingTime", time.Since(waitForAvailableStart),
 	)
 
diff --git a/test/integration/multikueue/enabled_integration_test.go b/test/integration/multikueue/enabled_integration_test.go
index 36385c0c7..378dc0421 100644
--- a/test/integration/multikueue/enabled_integration_test.go
+++ b/test/integration/multikueue/enabled_integration_test.go
@@ -111,7 +111,7 @@ var _ = ginkgo.Describe("MultiKueue when not all integrations are enabled", gink
 		})
 
 		managerCq = utiltesting.MakeClusterQueue("q1").
-			AdmissionChecks(multiKueueAC.Name).
+			AdmissionChecks(kueue.AdmissionCheckReference(multiKueueAC.Name)).
 			Obj()
 		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerCq)).Should(gomega.Succeed())
 
@@ -171,7 +171,7 @@ var _ = ginkgo.Describe("MultiKueue when not all integrations are enabled", gink
 
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, multiKueueAC.Name)
+				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAC.Name))
 				g.Expect(acs).NotTo(gomega.BeNil())
 				g.Expect(acs.State).To(gomega.Equal(kueue.CheckStatePending))
 				g.Expect(acs.Message).To(gomega.Equal(`The workload got reservation on "worker1"`))
@@ -270,9 +270,9 @@ var _ = ginkgo.Describe("MultiKueue when not all integrations are enabled", gink
 		ginkgo.By("checking the workload creation was rejected in the management cluster", func() {
 			managerWl := &kueue.Workload{}
 			gomega.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, managerWl)).To(gomega.Succeed())
-			acs := workload.FindAdmissionCheck(managerWl.Status.AdmissionChecks, multiKueueAC.Name)
+			acs := workload.FindAdmissionCheck(managerWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAC.Name))
 			gomega.Expect(acs).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
-				Name:    multiKueueAC.Name,
+				Name:    kueue.AdmissionCheckReference(multiKueueAC.Name),
 				State:   kueue.CheckStateRejected,
 				Message: `No multikueue adapter found for owner kind "kubeflow.org/v2beta1, Kind=MPIJob"`,
 			}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime")))
diff --git a/test/integration/multikueue/jobs_test.go b/test/integration/multikueue/jobs_test.go
index 916861447..f2bbcd4eb 100644
--- a/test/integration/multikueue/jobs_test.go
+++ b/test/integration/multikueue/jobs_test.go
@@ -166,7 +166,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 		})
 
 		managerCq = utiltesting.MakeClusterQueue("q1").
-			AdmissionChecks(multiKueueAC.Name).
+			AdmissionChecks(kueue.AdmissionCheckReference(multiKueueAC.Name)).
 			Obj()
 		util.MustCreate(managerTestCluster.ctx, managerTestCluster.client, managerCq)
 
@@ -237,7 +237,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, multiKueueAC.Name)
+				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAC.Name))
 				g.Expect(acs).NotTo(gomega.BeNil())
 				g.Expect(acs.State).To(gomega.Equal(kueue.CheckStatePending))
 				g.Expect(acs.Message).To(gomega.Equal(`The workload got reservation on "worker1"`))
@@ -331,7 +331,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, multiKueueAC.Name)
+				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAC.Name))
 				g.Expect(acs).NotTo(gomega.BeNil())
 				g.Expect(acs.State).To(gomega.Equal(kueue.CheckStateReady))
 				g.Expect(acs.Message).To(gomega.Equal(`The workload got reservation on "worker1"`))
@@ -1033,7 +1033,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, multiKueueAC.Name)
+				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAC.Name))
 				g.Expect(acs).NotTo(gomega.BeNil())
 				g.Expect(acs.State).To(gomega.Equal(kueue.CheckStatePending))
 				g.Expect(acs.Message).To(gomega.Equal(`The workload got reservation on "worker1"`))
@@ -1150,7 +1150,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, multiKueueAC.Name)
+				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAC.Name))
 				g.Expect(acs).NotTo(gomega.BeNil())
 				g.Expect(acs.State).To(gomega.Equal(kueue.CheckStatePending))
 				g.Expect(acs.Message).To(gomega.Equal(`The workload got reservation on "worker1"`))
@@ -1434,9 +1434,9 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 			gomega.Eventually(func(g gomega.Gomega) {
 				createdWorkload := &kueue.Workload{}
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, multiKueueAC.Name)
+				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAC.Name))
 				g.Expect(acs).To(gomega.BeComparableTo(&kueue.AdmissionCheckState{
-					Name:  multiKueueAC.Name,
+					Name:  kueue.AdmissionCheckReference(multiKueueAC.Name),
 					State: kueue.CheckStatePending,
 				}, cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "Message")))
 
@@ -1596,7 +1596,7 @@ func admitWorkloadAndCheckWorkerCopies(acName string, wlLookupKey types.Namespac
 
 		gomega.Eventually(func(g gomega.Gomega) {
 			g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-			acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, acName)
+			acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(acName))
 			g.Expect(acs).NotTo(gomega.BeNil())
 			g.Expect(acs.State).To(gomega.Equal(kueue.CheckStateReady))
 			g.Expect(acs.Message).To(gomega.Equal(`The workload got reservation on "worker2"`))
diff --git a/test/integration/multikueue/no_gc_test.go b/test/integration/multikueue/no_gc_test.go
index c3fa4799e..13ae44952 100644
--- a/test/integration/multikueue/no_gc_test.go
+++ b/test/integration/multikueue/no_gc_test.go
@@ -131,7 +131,7 @@ var _ = ginkgo.Describe("MultiKueue no GC", ginkgo.Ordered, ginkgo.ContinueOnFai
 		})
 
 		managerCq = utiltesting.MakeClusterQueue("q1").
-			AdmissionChecks(multiKueueAC.Name).
+			AdmissionChecks(kueue.AdmissionCheckReference(multiKueueAC.Name)).
 			Obj()
 		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerCq)).Should(gomega.Succeed())
 
@@ -257,7 +257,7 @@ var _ = ginkgo.Describe("MultiKueue no GC", ginkgo.Ordered, ginkgo.ContinueOnFai
 		ginkgo.By("setting workload reservation in worker1, AC state is updated in manager and worker2 wl is removed", func() {
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
-				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, multiKueueAC.Name)
+				acs := workload.FindAdmissionCheck(createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckReference(multiKueueAC.Name))
 				g.Expect(acs).NotTo(gomega.BeNil())
 				g.Expect(acs.State).To(gomega.Equal(kueue.CheckStatePending))
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -267,7 +267,7 @@ var _ = ginkgo.Describe("MultiKueue no GC", ginkgo.Ordered, ginkgo.ContinueOnFai
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(managerTestCluster.client.Get(managerTestCluster.ctx, wlLookupKey, createdWorkload)).To(gomega.Succeed())
 				workload.SetAdmissionCheckState(&createdWorkload.Status.AdmissionChecks, kueue.AdmissionCheckState{
-					Name:  multiKueueAC.Name,
+					Name:  kueue.AdmissionCheckReference(multiKueueAC.Name),
 					State: kueue.CheckStateRejected,
 				}, realClock)
 				g.Expect(managerTestCluster.client.Status().Update(managerTestCluster.ctx, createdWorkload)).Should(gomega.Succeed())
diff --git a/test/integration/multikueue/setup_test.go b/test/integration/multikueue/setup_test.go
index 360542c87..a8ed8687f 100644
--- a/test/integration/multikueue/setup_test.go
+++ b/test/integration/multikueue/setup_test.go
@@ -31,8 +31,6 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/manager"
 
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
-	"sigs.k8s.io/kueue/pkg/controller/admissionchecks/multikueue"
-	"sigs.k8s.io/kueue/pkg/features"
 	utiltesting "sigs.k8s.io/kueue/pkg/util/testing"
 	"sigs.k8s.io/kueue/test/util"
 )
@@ -127,7 +125,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 		})
 
 		managerCq = utiltesting.MakeClusterQueue("q1").
-			AdmissionChecks(multiKueueAC.Name).
+			AdmissionChecks(kueue.AdmissionCheckReference(multiKueueAC.Name)).
 			Obj()
 		gomega.Expect(managerTestCluster.client.Create(managerTestCluster.ctx, managerCq)).Should(gomega.Succeed())
 
@@ -159,7 +157,7 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerMultiKueueSecret1, true)
 		util.ExpectObjectToBeDeleted(managerTestCluster.ctx, managerTestCluster.client, managerMultiKueueSecret2, true)
 	})
-	ginkgo.It("Should properly manage the active condition of AdmissionChecks and MultiKueueClusters, kubeconfig provided by secret, AdmissionCheckValidationRules disabled", func() {
+	ginkgo.It("Should properly manage the active condition of AdmissionChecks and MultiKueueClusters, kubeconfig provided by secret", func() {
 		ac := utiltesting.MakeAdmissionCheck("testing-ac").
 			ControllerName(kueue.MultiKueueControllerName).
 			Parameters(kueue.GroupVersion.Group, "MultiKueueConfig", "testing-config").
@@ -292,9 +290,6 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 	})
 
 	ginkgo.It("Should properly manage the active condition of AdmissionChecks and MultiKueueClusters, kubeconfig provided by file", func() {
-		ginkgo.By("Enabling AdmissionCheckValidationRules feature", func() {
-			features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.AdmissionCheckValidationRules, true)
-		})
 		ac := utiltesting.MakeAdmissionCheck("testing-ac").
 			ControllerName(kueue.MultiKueueControllerName).
 			Parameters(kueue.GroupVersion.Group, "MultiKueueConfig", "testing-config").
@@ -315,18 +310,6 @@ var _ = ginkgo.Describe("MultiKueue", ginkgo.Ordered, ginkgo.ContinueOnFailure,
 							Reason:  "BadConfig",
 							Message: `Cannot load the AdmissionChecks parameters: MultiKueueConfig.kueue.x-k8s.io "testing-config" not found`,
 						}, util.IgnoreConditionTimestampsAndObservedGeneration),
-						gomega.BeComparableTo(metav1.Condition{
-							Type:    kueue.AdmissionChecksSingleInstanceInClusterQueue,
-							Status:  metav1.ConditionTrue,
-							Reason:  multikueue.SingleInstanceReason,
-							Message: multikueue.SingleInstanceMessage,
-						}, util.IgnoreConditionTimestampsAndObservedGeneration),
-						gomega.BeComparableTo(metav1.Condition{
-							Type:    kueue.FlavorIndependentAdmissionCheck,
-							Status:  metav1.ConditionTrue,
-							Reason:  multikueue.FlavorIndependentCheckReason,
-							Message: multikueue.FlavorIndependentCheckMessage,
-						}, util.IgnoreConditionTimestampsAndObservedGeneration),
 					))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
diff --git a/test/integration/singlecluster/controller/admissionchecks/provisioning/provisioning_test.go b/test/integration/singlecluster/controller/admissionchecks/provisioning/provisioning_test.go
index 1d6a4cc39..f34ab6872 100644
--- a/test/integration/singlecluster/controller/admissionchecks/provisioning/provisioning_test.go
+++ b/test/integration/singlecluster/controller/admissionchecks/provisioning/provisioning_test.go
@@ -18,7 +18,6 @@ package provisioning
 
 import (
 	"fmt"
-	"time"
 
 	"github.com/google/go-cmp/cmp/cmpopts"
 	"github.com/onsi/ginkgo/v2"
@@ -35,7 +34,6 @@ import (
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/constants"
 	"sigs.k8s.io/kueue/pkg/controller/admissionchecks/provisioning"
-	"sigs.k8s.io/kueue/pkg/features"
 	"sigs.k8s.io/kueue/pkg/util/testing"
 	"sigs.k8s.io/kueue/pkg/workload"
 	"sigs.k8s.io/kueue/test/integration/framework"
@@ -109,7 +107,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 				ResourceGroup(*testing.MakeFlavorQuotas(flavorOnDemand).
 					Resource(resourceGPU, "5", "5").Obj()).
 				Cohort("cohort").
-				AdmissionChecks(ac.Name).
+				AdmissionChecks(kueue.AdmissionCheckReference(ac.Name)).
 				Obj()
 			util.MustCreate(ctx, k8sClient, cq)
 			util.ExpectClusterQueuesToBeActive(ctx, k8sClient, cq)
@@ -144,7 +142,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			wlKey = client.ObjectKeyFromObject(wl)
 			provReqKey = types.NamespacedName{
 				Namespace: wlKey.Namespace,
-				Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
+				Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 1),
 			}
 
 			admission = testing.MakeAdmission(cq.Name).
@@ -186,7 +184,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -201,7 +199,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -264,7 +262,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
 					g.Expect(util.SetQuotaReservation(ctx, k8sClient, &updatedWl, nil)).To(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -279,7 +277,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -316,7 +314,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Checking that the ETA is propagated to workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(state).NotTo(gomega.BeNil())
 					g.Expect(state.State).To(gomega.Equal(kueue.CheckStatePending))
 					g.Expect(state.Message).To(gomega.Equal("Not provisioned, ETA: 2024-02-22T10:36:40Z."))
@@ -338,7 +336,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Checking the admission check", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(state).NotTo(gomega.BeNil())
 					g.Expect(state.State).To(gomega.Equal(kueue.CheckStateReady))
 					g.Expect(state.PodSetUpdates).To(gomega.BeComparableTo([]kueue.PodSetUpdate{
@@ -369,7 +367,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -397,7 +395,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
 						kueue.AdmissionCheckState{
-							Name:    ac.Name,
+							Name:    kueue.AdmissionCheckReference(ac.Name),
 							State:   kueue.CheckStatePending,
 							Message: "Reset to Pending after eviction. Previously: Rejected",
 						},
@@ -427,7 +425,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 			})
 
 			ginkgo.By("Admitting the workload", func() {
@@ -468,7 +466,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
 						kueue.AdmissionCheckState{
-							Name:    ac.Name,
+							Name:    kueue.AdmissionCheckReference(ac.Name),
 							State:   kueue.CheckStatePending,
 							Message: "Reset to Pending after eviction. Previously: Rejected",
 						},
@@ -500,7 +498,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 			})
 
 			ginkgo.By("Setting the quota reservation to the workload", func() {
@@ -528,7 +526,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 
 					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
 						kueue.AdmissionCheckState{
-							Name:    ac.Name,
+							Name:    kueue.AdmissionCheckReference(ac.Name),
 							State:   kueue.CheckStatePending,
 							Message: "Reset to Pending after eviction. Previously: Rejected",
 						},
@@ -560,7 +558,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 			})
 
 			ginkgo.By("Setting the quota reservation to the workload", func() {
@@ -587,7 +585,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
 						kueue.AdmissionCheckState{
-							Name:  ac.Name,
+							Name:  kueue.AdmissionCheckReference(ac.Name),
 							State: kueue.CheckStateReady,
 						},
 						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
@@ -620,7 +618,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 
 					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
 						kueue.AdmissionCheckState{
-							Name:  ac.Name,
+							Name:  kueue.AdmissionCheckReference(ac.Name),
 							State: kueue.CheckStateReady,
 						},
 						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
@@ -640,7 +638,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 			})
 
 			ginkgo.By("Setting the quota reservation to the workload", func() {
@@ -684,7 +682,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
 						kueue.AdmissionCheckState{
-							Name:  ac.Name,
+							Name:  kueue.AdmissionCheckReference(ac.Name),
 							State: kueue.CheckStateReady,
 						},
 						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
@@ -697,7 +695,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -791,7 +789,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Checking the admission check state indicates an inactive check", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(state).NotTo(gomega.BeNil())
 					g.Expect(state.Message).To(gomega.Equal(provisioning.CheckInactiveMessage))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -802,7 +800,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -834,7 +832,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Checking the admission check is ready", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(state).NotTo(gomega.BeNil())
 					g.Expect(state.State).To(gomega.Equal(kueue.CheckStateReady))
 					g.Expect(state.PodSetUpdates).To(gomega.BeComparableTo([]kueue.PodSetUpdate{
@@ -882,7 +880,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Checking the admission check remains ready", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(state).NotTo(gomega.BeNil())
 					g.Expect(state.State).To(gomega.Equal(kueue.CheckStateReady))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -896,584 +894,6 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 		})
 	})
 
-	ginkgo.When("Feature KeepQuotaForProvReqRetry is enabled and a workload is using a pending provision admission check with BackOffLimitCount=0", func() {
-		var (
-			ns             *corev1.Namespace
-			wlKey          types.NamespacedName
-			provReqKey     types.NamespacedName
-			ac             *kueue.AdmissionCheck
-			pendingAC      *kueue.AdmissionCheck
-			prc            *kueue.ProvisioningRequestConfig
-			rf             *kueue.ResourceFlavor
-			cq             *kueue.ClusterQueue
-			lq             *kueue.LocalQueue
-			admission      *kueue.Admission
-			createdRequest autoscaling.ProvisioningRequest
-			updatedWl      kueue.Workload
-		)
-		ginkgo.JustBeforeEach(func() {
-			ginkgo.By("Enabling KeepQuotaForProvReqRetry feature", func() {
-				features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.KeepQuotaForProvReqRetry, true)
-			})
-
-			ns = util.CreateNamespaceFromPrefixWithLog(ctx, k8sClient, "provisioning-")
-
-			prc = baseConfigWithParameters.Clone().RetryLimit(0).Obj()
-
-			util.MustCreate(ctx, k8sClient, prc)
-
-			ac = testing.MakeAdmissionCheck("ac-prov").
-				ControllerName(kueue.ProvisioningRequestControllerName).
-				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", prc.Name).
-				Obj()
-			util.MustCreate(ctx, k8sClient, ac)
-
-			pendingAC = testing.MakeAdmissionCheck("pending-ac").
-				ControllerName("dummy-controller").
-				Obj()
-			util.MustCreate(ctx, k8sClient, pendingAC)
-
-			rf = testing.MakeResourceFlavor(flavorOnDemand).NodeLabel("ns1", "ns1v").Obj()
-			util.MustCreate(ctx, k8sClient, rf)
-
-			cq = testing.MakeClusterQueue("cluster-queue").
-				ResourceGroup(*testing.MakeFlavorQuotas(flavorOnDemand).
-					Resource(resourceGPU, "5", "5").Obj()).
-				Cohort("cohort").
-				AdmissionChecks(ac.Name, pendingAC.Name).
-				Obj()
-			util.MustCreate(ctx, k8sClient, cq)
-			gomega.Eventually(func(g gomega.Gomega) {
-				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cq), cq)).Should(gomega.Succeed())
-				g.Expect(cq.Status.Conditions).To(gomega.ContainElements(gomega.BeComparableTo(metav1.Condition{
-					Type:    kueue.ClusterQueueActive,
-					Status:  metav1.ConditionFalse,
-					Reason:  "AdmissionCheckInactive",
-					Message: "Can't admit new workloads: references inactive AdmissionCheck(s): [pending-ac].",
-				}, util.IgnoreConditionTimestampsAndObservedGeneration)))
-			}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-			lq = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(cq.Name).Obj()
-			util.MustCreate(ctx, k8sClient, lq)
-			gomega.Eventually(func(g gomega.Gomega) {
-				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(lq), lq)).Should(gomega.Succeed())
-				g.Expect(lq.Status.Conditions).To(gomega.ContainElements(gomega.BeComparableTo(metav1.Condition{
-					Type:    kueue.LocalQueueActive,
-					Status:  metav1.ConditionFalse,
-					Reason:  "ClusterQueueIsInactive",
-					Message: "Can't submit new workloads to clusterQueue",
-				}, util.IgnoreConditionTimestampsAndObservedGeneration)))
-			}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-			wl := testing.MakeWorkload("wl", ns.Name).
-				Queue(lq.Name).
-				PodSets(
-					*testing.MakePodSet("ps1", 3).
-						Request(corev1.ResourceCPU, "1").
-						Image("image").
-						Obj(),
-					*testing.MakePodSet("ps2", 6).
-						Request(corev1.ResourceCPU, "500m").
-						Request(customResourceOne, "1").
-						Limit(customResourceOne, "1").
-						Image("image").
-						Obj(),
-				).
-				Annotations(map[string]string{
-					"provreq.kueue.x-k8s.io/ValidUntilSeconds": "0",
-					"invalid-provreq-prefix/Foo":               "Bar"}).
-				Obj()
-			util.MustCreate(ctx, k8sClient, wl)
-			util.SetWorkloadsAdmissionCheck(ctx, k8sClient, wl, pendingAC.Name, kueue.CheckStateReady, false)
-
-			wlKey = client.ObjectKeyFromObject(wl)
-			provReqKey = types.NamespacedName{
-				Namespace: wlKey.Namespace,
-				Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
-			}
-
-			admission = testing.MakeAdmission(cq.Name).
-				PodSets(
-					kueue.PodSetAssignment{
-						Name: "ps1",
-						Flavors: map[corev1.ResourceName]kueue.ResourceFlavorReference{
-							corev1.ResourceCPU: kueue.ResourceFlavorReference(rf.Name),
-						},
-						ResourceUsage: map[corev1.ResourceName]resource.Quantity{
-							corev1.ResourceCPU: resource.MustParse("3"),
-						},
-						Count: ptr.To[int32](3),
-					},
-					kueue.PodSetAssignment{
-						Name: "ps2",
-						Flavors: map[corev1.ResourceName]kueue.ResourceFlavorReference{
-							corev1.ResourceCPU: kueue.ResourceFlavorReference(rf.Name),
-						},
-						ResourceUsage: map[corev1.ResourceName]resource.Quantity{
-							corev1.ResourceCPU: resource.MustParse("2"),
-						},
-						Count: ptr.To[int32](4),
-					},
-				).
-				Obj()
-		})
-
-		ginkgo.AfterEach(func() {
-			gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, rf, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, ac, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, pendingAC, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, prc, true)
-		})
-
-		ginkgo.It("Should reject an admission check if a workload is not Admitted, the ProvisioningRequest's condition is set to BookingExpired", func() {
-			ginkgo.By("Setting the admission check to the workload", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, pendingAC.Name, kueue.CheckStatePending, true)
-			})
-
-			ginkgo.By("Setting the quota reservation to the workload", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					gomega.Expect(util.SetQuotaReservation(ctx, k8sClient, &updatedWl, admission)).To(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the provisioning request as Provisioned", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).To(gomega.Succeed())
-					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
-						Type:   autoscaling.Provisioned,
-						Status: metav1.ConditionTrue,
-						Reason: autoscaling.Provisioned,
-					})
-					g.Expect(k8sClient.Status().Update(ctx, &createdRequest)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Checking if one admission check is ready, and the other is pending thus workload is not admitted", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-
-					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
-						kueue.AdmissionCheckState{
-							Name:  ac.Name,
-							State: kueue.CheckStateReady,
-						},
-						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
-					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
-						kueue.AdmissionCheckState{
-							Name:  pendingAC.Name,
-							State: kueue.CheckStatePending,
-						},
-						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					g.Expect(workload.IsAdmitted(&updatedWl)).To(gomega.BeFalse(), "The Workload should not be admitted")
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the ProvisioningRequest as BookingExpired", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
-					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
-						Type:   autoscaling.BookingExpired,
-						Status: metav1.ConditionTrue,
-						Reason: autoscaling.BookingExpired,
-					})
-					g.Expect(k8sClient.Status().Update(ctx, &createdRequest)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Checking if workload is deactivated, once had Rejected status in the status.admissionCheck[*] field, an event is emitted and a metric is increased", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
-						kueue.AdmissionCheckState{
-							Name:    ac.Name,
-							State:   kueue.CheckStatePending,
-							Message: "Reset to Pending after eviction. Previously: Rejected",
-						},
-						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
-					g.Expect(workload.IsActive(&updatedWl)).To(gomega.BeFalse(), "The workload should be deactivated")
-
-					ok, err := testing.HasEventAppeared(ctx, k8sClient, corev1.Event{
-						Reason:  "AdmissionCheckRejected",
-						Type:    corev1.EventTypeWarning,
-						Message: fmt.Sprintf("Deactivating workload because AdmissionCheck for %v was Rejected: ", ac.Name),
-					})
-					g.Expect(err).NotTo(gomega.HaveOccurred())
-					g.Expect(ok).To(gomega.BeTrue(), "The event should have appeared")
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-
-					g.Expect(workload.IsEvictedByDeactivation(&updatedWl)).To(gomega.BeTrue(), "The workload should be evicted by deactivation")
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-				util.ExpectEvictedWorkloadsTotalMetric(cq.Name, "DeactivatedDueToAdmissionCheck", 1)
-			})
-		})
-	})
-
-	ginkgo.When("FeatureGate KeepQuotaForProvReqRetry is enabled, and a workload is using a provision admission check with  BackoffLimitCount=1", func() {
-		var (
-			ns             *corev1.Namespace
-			wlKey          types.NamespacedName
-			provReqKey     types.NamespacedName
-			ac             *kueue.AdmissionCheck
-			pendingAC      *kueue.AdmissionCheck
-			prc            *kueue.ProvisioningRequestConfig
-			rf             *kueue.ResourceFlavor
-			cq             *kueue.ClusterQueue
-			lq             *kueue.LocalQueue
-			admission      *kueue.Admission
-			createdRequest autoscaling.ProvisioningRequest
-			updatedWl      kueue.Workload
-		)
-		ginkgo.JustBeforeEach(func() {
-			ginkgo.By("Enabling KeepQuotaForProvReqRetry feature", func() {
-				features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.KeepQuotaForProvReqRetry, true)
-			})
-
-			ns = util.CreateNamespaceFromPrefixWithLog(ctx, k8sClient, "provisioning-")
-			prc = baseConfigWithParameters.Clone().RetryLimit(1).BaseBackoff(1).Obj()
-			util.MustCreate(ctx, k8sClient, prc)
-
-			ac = testing.MakeAdmissionCheck("ac-prov").
-				ControllerName(kueue.ProvisioningRequestControllerName).
-				Parameters(kueue.GroupVersion.Group, "ProvisioningRequestConfig", prc.Name).
-				Obj()
-			util.MustCreate(ctx, k8sClient, ac)
-
-			pendingAC = testing.MakeAdmissionCheck("pending-ac").
-				ControllerName("dummy-controller").
-				Obj()
-			util.MustCreate(ctx, k8sClient, pendingAC)
-
-			rf = testing.MakeResourceFlavor("rf1").Label("ns1", "ns1v").Obj()
-			util.MustCreate(ctx, k8sClient, rf)
-
-			cq = testing.MakeClusterQueue("cluster-queue").
-				ResourceGroup(*testing.MakeFlavorQuotas(flavorOnDemand).
-					Resource(resourceGPU, "5", "5").Obj()).
-				Cohort("cohort").
-				AdmissionChecks(ac.Name, pendingAC.Name).
-				Obj()
-			util.MustCreate(ctx, k8sClient, cq)
-			lq = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(cq.Name).Obj()
-			util.MustCreate(ctx, k8sClient, lq)
-			wl := testing.MakeWorkload("wl", ns.Name).
-				Queue(lq.Name).
-				PodSets(
-					*testing.MakePodSet("ps1", 3).
-						Request(corev1.ResourceCPU, "1").
-						Image("image").
-						Obj(),
-					*testing.MakePodSet("ps2", 6).
-						Request(corev1.ResourceCPU, "500m").
-						Request(customResourceOne, "1").
-						Limit(customResourceOne, "1").
-						Image("image").
-						Obj(),
-				).
-				Obj()
-			util.MustCreate(ctx, k8sClient, wl)
-			util.SetWorkloadsAdmissionCheck(ctx, k8sClient, wl, pendingAC.Name, kueue.CheckStateReady, false)
-
-			wlKey = client.ObjectKeyFromObject(wl)
-			provReqKey = types.NamespacedName{
-				Namespace: wlKey.Namespace,
-				Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
-			}
-
-			admission = testing.MakeAdmission(cq.Name).
-				PodSets(
-					kueue.PodSetAssignment{
-						Name: "ps1",
-						Flavors: map[corev1.ResourceName]kueue.ResourceFlavorReference{
-							corev1.ResourceCPU: kueue.ResourceFlavorReference(rf.Name),
-						},
-						ResourceUsage: map[corev1.ResourceName]resource.Quantity{
-							corev1.ResourceCPU: resource.MustParse("3"),
-						},
-						Count: ptr.To[int32](3),
-					},
-					kueue.PodSetAssignment{
-						Name: "ps2",
-						Flavors: map[corev1.ResourceName]kueue.ResourceFlavorReference{
-							corev1.ResourceCPU: kueue.ResourceFlavorReference(rf.Name),
-						},
-						ResourceUsage: map[corev1.ResourceName]resource.Quantity{
-							corev1.ResourceCPU: resource.MustParse("2"),
-						},
-						Count: ptr.To[int32](4),
-					},
-				).
-				Obj()
-		})
-
-		ginkgo.AfterEach(func() {
-			gomega.Expect(util.DeleteNamespace(ctx, k8sClient, ns)).To(gomega.Succeed())
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, cq, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, rf, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, ac, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, pendingAC, true)
-			util.ExpectObjectToBeDeleted(ctx, k8sClient, prc, true)
-		})
-
-		ginkgo.It("Should set check as Pending after the first ProvisioningRequest fails, then as Ready if the second Provisioning request succeeds", func() {
-			ginkgo.By("Setting the admission check to the workload", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the quota reservation to the workload", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					g.Expect(util.SetQuotaReservation(ctx, k8sClient, &updatedWl, admission)).To(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the provision request-1 as Failed", func() {
-				provReqKey := types.NamespacedName{
-					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
-				}
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
-					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
-						Type:   autoscaling.Failed,
-						Status: metav1.ConditionTrue,
-						Reason: autoscaling.Failed,
-					})
-					g.Expect(k8sClient.Status().Update(ctx, &createdRequest)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Checking the admission check is pending", func() {
-				// use consistently with short interval to make sure it does not
-				// flip to a short period of time.
-				gomega.Consistently(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
-					g.Expect(state).NotTo(gomega.BeNil())
-					g.Expect(state.State).To(gomega.Equal(kueue.CheckStatePending))
-				}, time.Second, 10*time.Millisecond).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the provision request-2 as Provisioned", func() {
-				provReqKey := types.NamespacedName{
-					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
-				}
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
-					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
-						Type:   autoscaling.Provisioned,
-						Status: metav1.ConditionTrue,
-						Reason: autoscaling.Provisioned,
-					})
-					g.Expect(k8sClient.Status().Update(ctx, &createdRequest)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Checking the admission check is ready", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
-					g.Expect(state).NotTo(gomega.BeNil())
-					g.Expect(state.State).To(gomega.Equal(kueue.CheckStateReady))
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-		})
-
-		ginkgo.It("Should set check as Rejected, if every ProvisioningRequest retry fails", func() {
-			ginkgo.By("Setting the admission check to the workload", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the quota reservation to the workload", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					g.Expect(util.SetQuotaReservation(ctx, k8sClient, &updatedWl, admission)).To(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the provision request-1 as Failed", func() {
-				provReqKey := types.NamespacedName{
-					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
-				}
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
-					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
-						Type:   autoscaling.Failed,
-						Status: metav1.ConditionTrue,
-						Reason: autoscaling.Failed,
-					})
-					g.Expect(k8sClient.Status().Update(ctx, &createdRequest)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Checking the admission check is pending", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
-					g.Expect(state).NotTo(gomega.BeNil())
-					g.Expect(state.State).To(gomega.Equal(kueue.CheckStatePending))
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the provision request-2 as Failed", func() {
-				provReqKey := types.NamespacedName{
-					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
-				}
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
-					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
-						Type:   autoscaling.Failed,
-						Status: metav1.ConditionTrue,
-						Reason: autoscaling.Failed,
-					})
-					g.Expect(k8sClient.Status().Update(ctx, &createdRequest)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Checking if workload is deactivated, once had Rejected status in the status.admissionCheck[*] field, an event is emitted and a metric is increased", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-
-					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
-						kueue.AdmissionCheckState{
-							Name:    ac.Name,
-							State:   kueue.CheckStatePending,
-							Message: "Reset to Pending after eviction. Previously: Rejected",
-						},
-						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
-					g.Expect(workload.IsActive(&updatedWl)).To(gomega.BeFalse())
-
-					ok, err := testing.HasEventAppeared(ctx, k8sClient, corev1.Event{
-						Reason:  "AdmissionCheckRejected",
-						Type:    corev1.EventTypeWarning,
-						Message: fmt.Sprintf("Deactivating workload because AdmissionCheck for %v was Rejected: ", ac.Name),
-					})
-					g.Expect(err).NotTo(gomega.HaveOccurred())
-					g.Expect(ok).To(gomega.BeTrue())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-
-					g.Expect(workload.IsEvictedByDeactivation(&updatedWl)).To(gomega.BeTrue())
-					util.ExpectEvictedWorkloadsTotalMetric(cq.Name, "DeactivatedDueToAdmissionCheck", 1)
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-		})
-
-		ginkgo.It("Should set a check as Pending if a workload is not Admitted, and the ProvisioningRequest's condition is set to BookingExpired", func() {
-			ginkgo.By("Setting the admission check to the workload", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, pendingAC.Name, kueue.CheckStatePending, true)
-			})
-
-			ginkgo.By("Setting the quota reservation to the workload", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					g.Expect(util.SetQuotaReservation(ctx, k8sClient, &updatedWl, admission)).To(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the provisioning request as Provisioned", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).To(gomega.Succeed())
-					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
-						Type:   autoscaling.Provisioned,
-						Status: metav1.ConditionTrue,
-						Reason: autoscaling.Provisioned,
-					})
-					g.Expect(k8sClient.Status().Update(ctx, &createdRequest)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Checking if one admission check is ready, and the other is pending thus workload is not admitted", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
-						kueue.AdmissionCheckState{
-							Name:  ac.Name,
-							State: kueue.CheckStateReady,
-						},
-						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
-					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
-						kueue.AdmissionCheckState{
-							Name:  pendingAC.Name,
-							State: kueue.CheckStatePending,
-						},
-						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates"))))
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					g.Expect(workload.IsAdmitted(&updatedWl)).To(gomega.BeFalse(), "The workload shouldn't be admitted")
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Setting the ProvisioningRequest as BookingExpired", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
-					apimeta.SetStatusCondition(&createdRequest.Status.Conditions, metav1.Condition{
-						Type:   autoscaling.BookingExpired,
-						Status: metav1.ConditionTrue,
-						Reason: autoscaling.BookingExpired,
-					})
-					g.Expect(k8sClient.Status().Update(ctx, &createdRequest)).Should(gomega.Succeed())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-
-			ginkgo.By("Checking if the admission check is pending and the request is retried", func() {
-				gomega.Eventually(func(g gomega.Gomega) {
-					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
-						kueue.AdmissionCheckState{
-							Name:  ac.Name,
-							State: kueue.CheckStatePending,
-						},
-						cmpopts.IgnoreFields(kueue.AdmissionCheckState{}, "LastTransitionTime", "PodSetUpdates", "Message"))))
-
-					provReqKey = types.NamespacedName{
-						Namespace: wlKey.Namespace,
-						Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
-					}
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).To(gomega.Succeed())
-					provReqKey = types.NamespacedName{
-						Namespace: wlKey.Namespace,
-						Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
-					}
-					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).To(testing.BeNotFoundError())
-				}, util.Timeout, util.Interval).Should(gomega.Succeed())
-			})
-		})
-	})
-
 	ginkgo.When("Workload uses a provision admission check with BackoffLimitCount=1", func() {
 		var (
 			ns             *corev1.Namespace
@@ -1511,8 +931,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 				ResourceGroup(*testing.MakeFlavorQuotas(flavorOnDemand).
 					Resource(resourceGPU, "5", "5").Obj()).
 				Cohort("cohort").
-				AdmissionChecks(ac.Name).
-				AdmissionChecks(ac.Name, readyAC.Name).
+				AdmissionChecks(kueue.AdmissionCheckReference(ac.Name), kueue.AdmissionCheckReference(readyAC.Name)).
 				Obj()
 			util.MustCreate(ctx, k8sClient, cq)
 			lq = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(cq.Name).Obj()
@@ -1533,7 +952,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 				).
 				Obj()
 			util.MustCreate(ctx, k8sClient, wl)
-			util.SetWorkloadsAdmissionCheck(ctx, k8sClient, wl, readyAC.Name, kueue.CheckStateReady, false)
+			util.SetWorkloadsAdmissionCheck(ctx, k8sClient, wl, kueue.AdmissionCheckReference(readyAC.Name), kueue.CheckStateReady, false)
 
 			wlKey = client.ObjectKeyFromObject(wl)
 			admission = testing.MakeAdmission(cq.Name).
@@ -1575,7 +994,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -1589,7 +1008,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the provision request-1 as Failed", func() {
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 1),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1615,10 +1034,10 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 					_, evicted := workload.IsEvictedByAdmissionCheck(&updatedWl)
 					g.Expect(evicted).To(gomega.BeTrue())
-					check := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					check := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(check).NotTo(gomega.BeNil())
 					g.Expect(check.State).To(gomega.Equal(kueue.CheckStatePending))
-					check = workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, readyAC.Name)
+					check = workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(readyAC.Name))
 					g.Expect(check).NotTo(gomega.BeNil())
 					g.Expect(check.State).To(gomega.Equal(kueue.CheckStatePending))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -1651,7 +1070,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 				gomega.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 2),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1661,7 +1080,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the provision request-2 as Provisioned", func() {
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 2),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1677,7 +1096,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Checking the admission check is ready", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(state).NotTo(gomega.BeNil())
 					g.Expect(state.State).To(gomega.Equal(kueue.CheckStateReady))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -1688,7 +1107,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -1702,7 +1121,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the provision request-1 as Failed", func() {
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 1),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1728,10 +1147,10 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 					_, evicted := workload.IsEvictedByAdmissionCheck(&updatedWl)
 					g.Expect(evicted).To(gomega.BeTrue())
-					check := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					check := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(check).NotTo(gomega.BeNil())
 					g.Expect(check.State).To(gomega.Equal(kueue.CheckStatePending))
-					check = workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, readyAC.Name)
+					check = workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(readyAC.Name))
 					g.Expect(check).NotTo(gomega.BeNil())
 					g.Expect(check.State).To(gomega.Equal(kueue.CheckStatePending))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -1764,7 +1183,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 				gomega.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 2),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1774,7 +1193,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the provision request-2 as Failed", func() {
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 2),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1793,7 +1212,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 
 					g.Expect(updatedWl.Status.AdmissionChecks).To(gomega.ContainElement(gomega.BeComparableTo(
 						kueue.AdmissionCheckState{
-							Name:    ac.Name,
+							Name:    kueue.AdmissionCheckReference(ac.Name),
 							State:   kueue.CheckStatePending,
 							Message: "Reset to Pending after eviction. Previously: Rejected",
 						},
@@ -1822,7 +1241,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the admission check to the workload", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
-					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, ac.Name, kueue.CheckStatePending, false)
+					util.SetWorkloadsAdmissionCheck(ctx, k8sClient, &updatedWl, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStatePending, false)
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
@@ -1836,7 +1255,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the provision request-1 as BookingExpired", func() {
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 1),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 1),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1862,10 +1281,10 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 					_, evicted := workload.IsEvictedByAdmissionCheck(&updatedWl)
 					g.Expect(evicted).To(gomega.BeTrue())
-					check := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					check := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(check).NotTo(gomega.BeNil())
 					g.Expect(check.State).To(gomega.Equal(kueue.CheckStatePending))
-					check = workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, readyAC.Name)
+					check = workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(readyAC.Name))
 					g.Expect(check).NotTo(gomega.BeNil())
 					g.Expect(check.State).To(gomega.Equal(kueue.CheckStatePending))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -1898,7 +1317,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 				gomega.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 2),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1908,7 +1327,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Setting the provision request-2 as Provisioned", func() {
 				provReqKey := types.NamespacedName{
 					Namespace: wlKey.Namespace,
-					Name:      provisioning.ProvisioningRequestName(wlKey.Name, ac.Name, 2),
+					Name:      provisioning.ProvisioningRequestName(wlKey.Name, kueue.AdmissionCheckReference(ac.Name), 2),
 				}
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, provReqKey, &createdRequest)).Should(gomega.Succeed())
@@ -1924,7 +1343,7 @@ var _ = ginkgo.Describe("Provisioning", ginkgo.Ordered, ginkgo.ContinueOnFailure
 			ginkgo.By("Checking the admission check is ready", func() {
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, ac.Name)
+					state := workload.FindAdmissionCheck(updatedWl.Status.AdmissionChecks, kueue.AdmissionCheckReference(ac.Name))
 					g.Expect(state).NotTo(gomega.BeNil())
 					g.Expect(state.State).To(gomega.Equal(kueue.CheckStateReady))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
diff --git a/test/integration/singlecluster/controller/core/admissioncheck_controller_test.go b/test/integration/singlecluster/controller/core/admissioncheck_controller_test.go
index b2f1e06a3..27cfc621d 100644
--- a/test/integration/singlecluster/controller/core/admissioncheck_controller_test.go
+++ b/test/integration/singlecluster/controller/core/admissioncheck_controller_test.go
@@ -100,7 +100,7 @@ var _ = ginkgo.Describe("AdmissionCheck controller", ginkgo.Ordered, ginkgo.Cont
 			ginkgo.By("Change clusterQueue's checks")
 			gomega.Eventually(func(g gomega.Gomega) {
 				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(clusterQueue), &cq)).Should(gomega.Succeed())
-				cq.Spec.AdmissionChecks = []string{"check2"}
+				cq.Spec.AdmissionChecks = []kueue.AdmissionCheckReference{"check2"}
 				g.Expect(k8sClient.Update(ctx, &cq)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
diff --git a/test/integration/singlecluster/controller/core/clusterqueue_controller_test.go b/test/integration/singlecluster/controller/core/clusterqueue_controller_test.go
index b1f16b481..3607c8d98 100644
--- a/test/integration/singlecluster/controller/core/clusterqueue_controller_test.go
+++ b/test/integration/singlecluster/controller/core/clusterqueue_controller_test.go
@@ -130,7 +130,7 @@ var _ = ginkgo.Describe("ClusterQueue controller", ginkgo.Ordered, ginkgo.Contin
 						Resource(resourceGPU, "5", "5").Obj(),
 				).
 				Cohort("cohort").
-				AdmissionChecks(ac.Name).
+				AdmissionChecks(kueue.AdmissionCheckReference(ac.Name)).
 				Obj()
 			util.MustCreate(ctx, k8sClient, clusterQueue)
 			localQueue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj()
@@ -305,7 +305,7 @@ var _ = ginkgo.Describe("ClusterQueue controller", ginkgo.Ordered, ginkgo.Contin
 
 			ginkgo.By("Setting the admission check for the first 4 workloads")
 			for _, w := range workloads[:4] {
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, w, ac.Name, kueue.CheckStateReady, true)
+				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, w, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStateReady, true)
 			}
 
 			gomega.Eventually(func(g gomega.Gomega) {
@@ -645,9 +645,6 @@ var _ = ginkgo.Describe("ClusterQueue controller", ginkgo.Ordered, ginkgo.Contin
 		})
 
 		ginkgo.It("Should update status conditions when flavors are created", func() {
-			ginkgo.By("Enabling AdmissionCheckValidationRules feature", func() {
-				features.SetFeatureGateDuringTest(ginkgo.GinkgoTB(), features.AdmissionCheckValidationRules, true)
-			})
 			check1 = testing.MakeAdmissionCheck("check1").ControllerName("ac-controller").Obj()
 			util.MustCreate(ctx, k8sClient, check1)
 			util.SetAdmissionCheckActive(ctx, k8sClient, check1, metav1.ConditionTrue)
@@ -841,7 +838,7 @@ var _ = ginkgo.Describe("ClusterQueue controller", ginkgo.Ordered, ginkgo.Contin
 			gomega.Eventually(func(g gomega.Gomega) {
 				var updatedCq kueue.ClusterQueue
 				g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(cq), &updatedCq)).Should(gomega.Succeed())
-				updatedCq.Spec.AdmissionChecks = []string{"check1"}
+				updatedCq.Spec.AdmissionChecks = []kueue.AdmissionCheckReference{"check1"}
 				updatedCq.Spec.AdmissionChecksStrategy = nil
 				g.Expect(k8sClient.Update(ctx, &updatedCq)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -872,7 +869,7 @@ var _ = ginkgo.Describe("ClusterQueue controller", ginkgo.Ordered, ginkgo.Contin
 			check = testing.MakeAdmissionCheck("check").ControllerName("check-controller").Obj()
 			util.MustCreate(ctx, k8sClient, check)
 
-			cq = testing.MakeClusterQueue("foo-cq").AdmissionChecks(check.Name).Obj()
+			cq = testing.MakeClusterQueue("foo-cq").AdmissionChecks(kueue.AdmissionCheckReference(check.Name)).Obj()
 			lq = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(cq.Name).Obj()
 			util.MustCreate(ctx, k8sClient, lq)
 			util.MustCreate(ctx, k8sClient, cq)
@@ -895,7 +892,7 @@ var _ = ginkgo.Describe("ClusterQueue controller", ginkgo.Ordered, ginkgo.Contin
 			wl := testing.MakeWorkload("workload", ns.Name).Queue(lq.Name).Obj()
 			util.MustCreate(ctx, k8sClient, wl)
 			gomega.Expect(util.SetQuotaReservation(ctx, k8sClient, wl, testing.MakeAdmission(cq.Name).Obj())).To(gomega.Succeed())
-			util.SetWorkloadsAdmissionCheck(ctx, k8sClient, wl, check.Name, kueue.CheckStateReady, true)
+			util.SetWorkloadsAdmissionCheck(ctx, k8sClient, wl, kueue.AdmissionCheckReference(check.Name), kueue.CheckStateReady, true)
 			gomega.Eventually(func(g gomega.Gomega) {
 				key := client.ObjectKeyFromObject(wl)
 				updatedWl := &kueue.Workload{}
diff --git a/test/integration/singlecluster/controller/core/localqueue_controller_test.go b/test/integration/singlecluster/controller/core/localqueue_controller_test.go
index b9025fc3d..f88ca719c 100644
--- a/test/integration/singlecluster/controller/core/localqueue_controller_test.go
+++ b/test/integration/singlecluster/controller/core/localqueue_controller_test.go
@@ -96,7 +96,7 @@ var _ = ginkgo.Describe("Queue controller", ginkgo.Ordered, ginkgo.ContinueOnFai
 				*testing.MakeFlavorQuotas(flavorModelC).Resource(resourceGPU, "5", "5").Obj(),
 			).
 			Cohort("cohort").
-			AdmissionChecks(ac.Name).
+			AdmissionChecks(kueue.AdmissionCheckReference(ac.Name)).
 			Obj()
 		queue = testing.MakeLocalQueue("queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj()
 		util.MustCreate(ctx, k8sClient, queue)
@@ -366,7 +366,7 @@ var _ = ginkgo.Describe("Queue controller", ginkgo.Ordered, ginkgo.ContinueOnFai
 
 		ginkgo.By("Setting the workloads admission checks")
 		for _, w := range workloads {
-			util.SetWorkloadsAdmissionCheck(ctx, k8sClient, w, ac.Name, kueue.CheckStateReady, true)
+			util.SetWorkloadsAdmissionCheck(ctx, k8sClient, w, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStateReady, true)
 		}
 
 		gomega.Eventually(func(g gomega.Gomega) {
@@ -588,7 +588,7 @@ var _ = ginkgo.Describe("Queue controller", ginkgo.Ordered, ginkgo.ContinueOnFai
 
 		ginkgo.By("Setting the workloads admission checks", func() {
 			for _, w := range workloads {
-				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, w, ac.Name, kueue.CheckStateReady, true)
+				util.SetWorkloadsAdmissionCheck(ctx, k8sClient, w, kueue.AdmissionCheckReference(ac.Name), kueue.CheckStateReady, true)
 			}
 
 			gomega.Eventually(func(g gomega.Gomega) {
diff --git a/test/integration/singlecluster/controller/core/workload_controller_test.go b/test/integration/singlecluster/controller/core/workload_controller_test.go
index cb026b1ad..1c39e4ad6 100644
--- a/test/integration/singlecluster/controller/core/workload_controller_test.go
+++ b/test/integration/singlecluster/controller/core/workload_controller_test.go
@@ -211,7 +211,7 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
 					g.Expect(slices.Map(createdWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string {
-						return c.Name
+						return string(c.Name)
 					})).Should(gomega.ConsistOf("check1", "check2"))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -242,7 +242,7 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 				queueKey := client.ObjectKeyFromObject(clusterQueue)
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, queueKey, &createdQueue)).To(gomega.Succeed())
-					createdQueue.Spec.AdmissionChecks = []string{"check2", "check3"}
+					createdQueue.Spec.AdmissionChecks = []kueue.AdmissionCheckReference{"check2", "check3"}
 					g.Expect(k8sClient.Update(ctx, &createdQueue)).Should(gomega.Succeed())
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
@@ -250,7 +250,7 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
 					g.Expect(slices.Map(createdWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string {
-						return c.Name
+						return string(c.Name)
 					})).Should(gomega.ConsistOf("check2", "check3"))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
@@ -268,7 +268,7 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
 					g.Expect(slices.Map(createdWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string {
-						return c.Name
+						return string(c.Name)
 					})).Should(gomega.ConsistOf("check1", "check2"))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
@@ -323,7 +323,7 @@ var _ = ginkgo.Describe("Workload controller", ginkgo.Ordered, ginkgo.ContinueOn
 				gomega.Eventually(func(g gomega.Gomega) {
 					g.Expect(k8sClient.Get(ctx, wlKey, &createdWl)).To(gomega.Succeed())
 					g.Expect(slices.Map(createdWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string {
-						return c.Name
+						return string(c.Name)
 					})).Should(gomega.ConsistOf("check1", "check2"))
 				}, 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 169892abb..6a6e8294a 100644
--- a/test/integration/singlecluster/controller/jobs/job/job_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/job/job_controller_test.go
@@ -478,11 +478,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 				gomega.Eventually(func(g gomega.Gomega) {
 					createdWl := kueue.Workload{}
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &createdWl)).To(gomega.Succeed())
-					g.Expect(createdWl.OwnerReferences).To(gomega.ContainElement(
-						gomega.BeComparableTo(metav1.OwnerReference{
-							Name: job.Name,
-							UID:  job.UID,
-						}, cmpopts.IgnoreFields(metav1.OwnerReference{}, "APIVersion", "Kind", "Controller", "BlockOwnerDeletion"))))
+					util.MustHaveOwnerReference(g, createdWl.OwnerReferences, job, k8sClient.Scheme())
 				}, util.LongTimeout, util.Interval).Should(gomega.Succeed())
 			})
 		})
@@ -523,14 +519,7 @@ var _ = ginkgo.Describe("Job controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 				gomega.Eventually(func(g gomega.Gomega) {
 					createdWl := kueue.Workload{}
 					g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &createdWl)).To(gomega.Succeed())
-
-					g.Expect(createdWl.OwnerReferences).To(gomega.ContainElement(
-						gomega.BeComparableTo(metav1.OwnerReference{
-							Name: job.Name,
-							UID:  job.UID,
-						}, cmpopts.IgnoreFields(metav1.OwnerReference{}, "APIVersion", "Kind", "Controller", "BlockOwnerDeletion")),
-					))
-
+					util.MustHaveOwnerReference(g, createdWl.OwnerReferences, job, k8sClient.Scheme())
 					// The workload is not marked as finished.
 					g.Expect(createdWl.Status.Conditions).ShouldNot(testing.HaveConditionStatusTrue(kueue.WorkloadFinished))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
@@ -2187,7 +2176,7 @@ var _ = ginkgo.Describe("Job controller interacting with Workload controller whe
 				g.Expect(k8sClient.Get(ctx, jobKey, job)).Should(gomega.Succeed())
 				job.Status.Active = 1
 				job.Status.Ready = ptr.To[int32](1)
-				gomega.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
+				g.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
 			ginkgo.By("ensuring workload has PodsReady=True condition")
@@ -2208,7 +2197,7 @@ var _ = ginkgo.Describe("Job controller interacting with Workload controller whe
 				job.Status.Active = 0
 				job.Status.Ready = ptr.To[int32](0)
 				job.Status.Failed = 1
-				gomega.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
+				g.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
 			ginkgo.By("checking the workload is still admitted")
@@ -2246,7 +2235,7 @@ var _ = ginkgo.Describe("Job controller interacting with Workload controller whe
 				g.Expect(k8sClient.Get(ctx, jobKey, job)).Should(gomega.Succeed())
 				job.Status.Active = 1
 				job.Status.Ready = ptr.To[int32](1)
-				gomega.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
+				g.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
 			ginkgo.By("ensuring workload has PodsReady=True condition")
@@ -2267,7 +2256,7 @@ var _ = ginkgo.Describe("Job controller interacting with Workload controller whe
 				job.Status.Active = 0
 				job.Status.Ready = ptr.To[int32](0)
 				job.Status.Failed = 1
-				gomega.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
+				g.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
 			ginkgo.By("checking the workload is evicted")
@@ -2323,7 +2312,7 @@ var _ = ginkgo.Describe("Job controller interacting with Workload controller whe
 				g.Expect(k8sClient.Get(ctx, jobKey, job)).Should(gomega.Succeed())
 				job.Status.Active = 1
 				job.Status.Ready = ptr.To[int32](1)
-				gomega.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
+				g.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
 			ginkgo.By("ensuring workload has PodsReady=True condition")
@@ -2344,7 +2333,7 @@ var _ = ginkgo.Describe("Job controller interacting with Workload controller whe
 				job.Status.Active = 0
 				job.Status.Ready = ptr.To[int32](0)
 				job.Status.Failed = 1
-				gomega.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
+				g.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
 			ginkgo.By("ensuring workload has PodsReady=False condition")
@@ -2365,7 +2354,7 @@ var _ = ginkgo.Describe("Job controller interacting with Workload controller whe
 				job.Status.Active = 1
 				job.Status.Ready = ptr.To[int32](1)
 				job.Status.Failed = 1
-				gomega.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
+				g.Expect(k8sClient.Status().Update(ctx, job)).Should(gomega.Succeed())
 			}, util.Timeout, util.Interval).Should(gomega.Succeed())
 
 			ginkgo.By("ensuring workload has PodsReady=True condition")
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 e47f7bb78..16134dda2 100644
--- a/test/integration/singlecluster/controller/jobs/pod/pod_controller_test.go
+++ b/test/integration/singlecluster/controller/jobs/pod/pod_controller_test.go
@@ -878,12 +878,7 @@ var _ = ginkgo.Describe("Pod controller", ginkgo.Ordered, ginkgo.ContinueOnFailu
 								Message: "Pods succeeded: 2/2.",
 							}, util.IgnoreConditionTimestampsAndObservedGeneration),
 						))
-						g.Expect(createdWorkload.OwnerReferences).Should(gomega.ContainElement(metav1.OwnerReference{
-							APIVersion: "v1",
-							Kind:       "Pod",
-							Name:       replacementPod.Name,
-							UID:        replacementPod.UID,
-						}))
+						util.MustHaveOwnerReference(g, createdWorkload.OwnerReferences, replacementPod, k8sClient.Scheme())
 					}, util.Timeout, util.Interval).Should(gomega.Succeed())
 				})
 			})
diff --git a/test/integration/singlecluster/scheduler/preemption_test.go b/test/integration/singlecluster/scheduler/preemption_test.go
index 1cbe0ba5a..237c8c344 100644
--- a/test/integration/singlecluster/scheduler/preemption_test.go
+++ b/test/integration/singlecluster/scheduler/preemption_test.go
@@ -28,6 +28,7 @@ import (
 	"k8s.io/utils/ptr"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	kueuealpha "sigs.k8s.io/kueue/apis/kueue/v1alpha1"
 	kueue "sigs.k8s.io/kueue/apis/kueue/v1beta1"
 	"sigs.k8s.io/kueue/pkg/controller/constants"
 	"sigs.k8s.io/kueue/pkg/features"
@@ -910,4 +911,81 @@ var _ = ginkgo.Describe("Preemption", func() {
 			})
 		})
 	})
+	ginkgo.Context("In a multi-level cohort", func() {
+		var rootCohort, guaranteedCohort *kueuealpha.Cohort
+		var bestEffortCQ, guaranteedCQ *kueue.ClusterQueue
+		var defaultFlavor *kueue.ResourceFlavor
+
+		ginkgo.BeforeEach(func() {
+			defaultFlavor = testing.MakeResourceFlavor("default").Obj()
+			gomega.Expect(k8sClient.Create(ctx, defaultFlavor)).To(gomega.Succeed())
+
+			rootCohort = testing.MakeCohort("root").Obj()
+			gomega.Expect(k8sClient.Create(ctx, rootCohort)).To(gomega.Succeed())
+			guaranteedCohort = testing.MakeCohort("guaranteed").Parent("root").
+				ResourceGroup(
+					*testing.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "3").Obj(),
+				).Obj()
+			gomega.Expect(k8sClient.Create(ctx, guaranteedCohort)).To(gomega.Succeed())
+			bestEffortCQ = testing.MakeClusterQueue("best-effort").
+				Cohort("root").
+				ResourceGroup(
+					*testing.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "0").Obj(),
+				).
+				Preemption(kueue.ClusterQueuePreemption{
+					WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+					ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+				}).
+				Obj()
+			gomega.Expect(k8sClient.Create(ctx, bestEffortCQ)).To(gomega.Succeed())
+			guaranteedCQ = testing.MakeClusterQueue("guaranteed").
+				Cohort("guaranteed").ResourceGroup(
+				*testing.MakeFlavorQuotas("default").Resource(corev1.ResourceCPU, "0").Obj(),
+			).
+				Preemption(kueue.ClusterQueuePreemption{
+					WithinClusterQueue:  kueue.PreemptionPolicyLowerPriority,
+					ReclaimWithinCohort: kueue.PreemptionPolicyAny,
+				}).
+				Obj()
+			gomega.Expect(k8sClient.Create(ctx, guaranteedCQ)).To(gomega.Succeed())
+		})
+		ginkgo.It("workloads in guaranteed cq should have preferential access to the resources", func() {
+			var bestEffortLQ *kueue.LocalQueue
+			var guaranteedLQ *kueue.LocalQueue
+			var bestEffortWl, guaranteedWl *kueue.Workload
+
+			ginkgo.By("Create local queues", func() {
+				bestEffortLQ = testing.MakeLocalQueue("best-effort-lq", ns.Name).ClusterQueue(bestEffortCQ.Name).Obj()
+				gomega.Expect(k8sClient.Create(ctx, bestEffortLQ)).Should(gomega.Succeed())
+				guaranteedLQ = testing.MakeLocalQueue("guaranteed-lq", ns.Name).ClusterQueue(guaranteedCQ.Name).Obj()
+				gomega.Expect(k8sClient.Create(ctx, guaranteedLQ)).Should(gomega.Succeed())
+			})
+
+			ginkgo.By("Create a workload in bestEffortCQ and await for admission", func() {
+				bestEffortWl = testing.MakeWorkload("best-effort-wl", ns.Name).
+					Queue(bestEffortLQ.Name).
+					Priority(highPriority).
+					Request(corev1.ResourceCPU, "3").
+					Obj()
+				gomega.Expect(k8sClient.Create(ctx, bestEffortWl)).To(gomega.Succeed())
+				util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, bestEffortWl)
+			})
+
+			ginkgo.By("Create a workload in guaranteedCQ", func() {
+				guaranteedWl = testing.MakeWorkload("guaranteed-wl", ns.Name).
+					Queue(guaranteedLQ.Name).
+					Priority(midPriority).
+					Request(corev1.ResourceCPU, "3").
+					Obj()
+				gomega.Expect(k8sClient.Create(ctx, guaranteedWl)).To(gomega.Succeed())
+			})
+
+			ginkgo.By("Await for preemption of the workload in bestEffortCQ and admission of guaranteedWL", func() {
+				util.ExpectWorkloadsToBePreempted(ctx, k8sClient, bestEffortWl)
+				util.FinishEvictionForWorkloads(ctx, k8sClient, bestEffortWl)
+				util.ExpectWorkloadsToBePending(ctx, k8sClient, bestEffortWl)
+				util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, guaranteedWl)
+			})
+		})
+	})
 })
diff --git a/test/integration/singlecluster/scheduler/scheduler_test.go b/test/integration/singlecluster/scheduler/scheduler_test.go
index 75ea12e4b..8f7dbf240 100644
--- a/test/integration/singlecluster/scheduler/scheduler_test.go
+++ b/test/integration/singlecluster/scheduler/scheduler_test.go
@@ -1237,7 +1237,7 @@ var _ = ginkgo.Describe("Scheduler", func() {
 			devQueue := testing.MakeLocalQueue("dev-queue", ns.Name).ClusterQueue(devCQ.Name).Obj()
 			util.MustCreate(ctx, k8sClient, devQueue)
 
-			ginkgo.By("Creating two workloads for prod ClusterQueue")
+			ginkgo.By("Creating the first workload for the prod ClusterQueue")
 			pWl1 := testing.MakeWorkload("p-wl-1", ns.Name).Queue(prodQueue.Name).Request(corev1.ResourceCPU, "2").Obj()
 			util.MustCreate(ctx, k8sClient, pWl1)
 			util.ExpectWorkloadsToHaveQuotaReservation(ctx, k8sClient, prodCQ.Name, pWl1)
@@ -1251,9 +1251,8 @@ var _ = ginkgo.Describe("Scheduler", func() {
 			util.WaitForNextSecondAfterCreation(pWl2)
 			util.ExpectWorkloadsToBePending(ctx, k8sClient, dWl1, pWl2)
 
-			ginkgo.By("Finishing one workload for prod ClusterQueue")
+			ginkgo.By("Finishing the first workload for the prod ClusterQueue")
 			util.FinishWorkloads(ctx, k8sClient, pWl1)
-			util.ExpectWorkloadsToBePending(ctx, k8sClient, dWl1, pWl2)
 
 			// The pWl2 workload gets accepted, even though it was created after dWl1.
 			util.ExpectWorkloadsToHaveQuotaReservation(ctx, k8sClient, prodCQ.Name, pWl2)
diff --git a/test/integration/singlecluster/scheduler/workload_controller_test.go b/test/integration/singlecluster/scheduler/workload_controller_test.go
index 30ff1dc35..489ae502e 100644
--- a/test/integration/singlecluster/scheduler/workload_controller_test.go
+++ b/test/integration/singlecluster/scheduler/workload_controller_test.go
@@ -139,8 +139,8 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).Should(gomega.Succeed())
 					g.Expect(workload.HasQuotaReservation(&updatedWl)).Should(gomega.BeTrue(), "should have quota reservation")
 
-					checks := slices.Map(updatedWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return c.Name })
-					g.Expect(checks).Should(gomega.ConsistOf("check1", "check2"))
+					checks := slices.Map(updatedWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) kueue.AdmissionCheckReference { return c.Name })
+					g.Expect(checks).Should(gomega.ConsistOf(kueue.AdmissionCheckReference("check1"), kueue.AdmissionCheckReference("check2")))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 				gomega.Expect(workload.IsAdmitted(&updatedWl)).To(gomega.BeFalse())
 			})
@@ -156,8 +156,8 @@ var _ = ginkgo.Describe("Workload controller with scheduler", func() {
 						*testing.MakeAdmissionCheckStrategyRule("check3").Obj()}
 					g.Expect(k8sClient.Update(ctx, &createdQueue)).To(gomega.Succeed())
 					g.Expect(k8sClient.Get(ctx, wlKey, &updatedWl)).To(gomega.Succeed())
-					checks := slices.Map(updatedWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) string { return c.Name })
-					g.Expect(checks).Should(gomega.ConsistOf("check1", "check3"))
+					checks := slices.Map(updatedWl.Status.AdmissionChecks, func(c *kueue.AdmissionCheckState) kueue.AdmissionCheckReference { return c.Name })
+					g.Expect(checks).Should(gomega.ConsistOf(kueue.AdmissionCheckReference("check1"), kueue.AdmissionCheckReference("check3")))
 				}, util.Timeout, util.Interval).Should(gomega.Succeed())
 			})
 
diff --git a/test/integration/singlecluster/tas/tas_test.go b/test/integration/singlecluster/tas/tas_test.go
index a62b83e11..e4835ebba 100644
--- a/test/integration/singlecluster/tas/tas_test.go
+++ b/test/integration/singlecluster/tas/tas_test.go
@@ -217,7 +217,7 @@ var _ = ginkgo.Describe("Topology Aware Scheduling", ginkgo.Ordered, func() {
 			clusterQueue = testing.MakeClusterQueue("cq").
 				ResourceGroup(
 					*testing.MakeFlavorQuotas(tasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
-				).AdmissionChecks(admissionCheck.Name).Obj()
+				).AdmissionChecks(kueue.AdmissionCheckReference(admissionCheck.Name)).Obj()
 			util.MustCreate(ctx, k8sClient, clusterQueue)
 
 			gomega.Eventually(func(g gomega.Gomega) {
@@ -242,7 +242,7 @@ var _ = ginkgo.Describe("Topology Aware Scheduling", ginkgo.Ordered, func() {
 			clusterQueue = testing.MakeClusterQueue("cq").
 				ResourceGroup(
 					*testing.MakeFlavorQuotas(tasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj(),
-				).AdmissionChecks(admissionCheck.Name).Obj()
+				).AdmissionChecks(kueue.AdmissionCheckReference(admissionCheck.Name)).Obj()
 			util.MustCreate(ctx, k8sClient, clusterQueue)
 
 			gomega.Eventually(func(g gomega.Gomega) {
@@ -1214,6 +1214,7 @@ var _ = ginkgo.Describe("Topology Aware Scheduling", ginkgo.Ordered, func() {
 					ResourceGroup(*testing.MakeFlavorQuotas(tasFlavor.Name).Resource(corev1.ResourceCPU, "5").Obj()).
 					Obj()
 				util.MustCreate(ctx, k8sClient, clusterQueue)
+				util.ExpectClusterQueuesToBeActive(ctx, k8sClient, clusterQueue)
 
 				localQueue = testing.MakeLocalQueue("local-queue", ns.Name).ClusterQueue(clusterQueue.Name).Obj()
 				util.MustCreate(ctx, k8sClient, localQueue)
@@ -1285,6 +1286,74 @@ var _ = ginkgo.Describe("Topology Aware Scheduling", ginkgo.Ordered, func() {
 					util.ExpectPendingWorkloadsMetric(clusterQueue, 0, 0)
 				})
 			})
+
+			ginkgo.It("should admit workload when node gets required label added", func() {
+				var (
+					wl1 *kueue.Workload
+				)
+				customLabelKey := "custom-label-key-1"
+				customLabelCorrectValue := "value-1"
+				customLabelWrongValue := "value-2"
+
+				ginkgo.By("creating a node missing the required label", func() {
+					nodes = []corev1.Node{
+						*testingnode.MakeNode("node-missing-label").
+							Label("node-group", "tas").
+							Label(testing.DefaultBlockTopologyLevel, "b1").
+							Label(testing.DefaultRackTopologyLevel, "r1").
+							Label(corev1.LabelHostname, "node-missing-label").
+							StatusAllocatable(corev1.ResourceList{
+								corev1.ResourceCPU:    resource.MustParse("1"),
+								corev1.ResourceMemory: resource.MustParse("1Gi"),
+								corev1.ResourcePods:   resource.MustParse("10"),
+							}).
+							Ready().
+							Obj(),
+					}
+					util.CreateNodesWithStatus(ctx, k8sClient, nodes)
+				})
+
+				ginkgo.By("creating a workload requiring the missing label via NodeSelector", func() {
+					wl1 = testing.MakeWorkload("wl-needs-label", ns.Name).
+						Queue(localQueue.Name).
+						PodSets(*testing.MakePodSet("main", 1).
+							NodeSelector(map[string]string{customLabelKey: customLabelCorrectValue}).
+							Request(corev1.ResourceCPU, "1").
+							Obj()).
+						Obj()
+					util.MustCreate(ctx, k8sClient, wl1)
+				})
+
+				ginkgo.By("verify the workload is inadmissible due to missing label", func() {
+					util.ExpectWorkloadsToBePending(ctx, k8sClient, wl1)
+					util.ExpectPendingWorkloadsMetric(clusterQueue, 0, 1)
+				})
+
+				ginkgo.By("Add a label to the node with correct key but wrong value", func() {
+					nodeToUpdate := &corev1.Node{}
+					gomega.Expect(k8sClient.Get(ctx, client.ObjectKey{Name: nodes[0].Name}, nodeToUpdate)).Should(gomega.Succeed())
+					nodeToUpdate.Labels[customLabelKey] = customLabelWrongValue
+					gomega.Expect(k8sClient.Update(ctx, nodeToUpdate)).Should(gomega.Succeed())
+				})
+
+				ginkgo.By("verify the workload is inadmissible due to wrong value in the label", func() {
+					util.ExpectWorkloadsToBePending(ctx, k8sClient, wl1)
+					util.ExpectPendingWorkloadsMetric(clusterQueue, 0, 1)
+				})
+
+				ginkgo.By("Add the correct label to the node", func() {
+					nodeToUpdate := &corev1.Node{}
+					gomega.Expect(k8sClient.Get(ctx, client.ObjectKey{Name: nodes[0].Name}, nodeToUpdate)).Should(gomega.Succeed())
+					nodeToUpdate.Labels[customLabelKey] = customLabelCorrectValue
+					gomega.Expect(k8sClient.Update(ctx, nodeToUpdate)).Should(gomega.Succeed())
+				})
+
+				ginkgo.By("verify the workload gets admitted after label is added", func() {
+					util.ExpectWorkloadsToBeAdmitted(ctx, k8sClient, wl1)
+					util.ExpectReservingActiveWorkloadsMetric(clusterQueue, 1)
+					util.ExpectPendingWorkloadsMetric(clusterQueue, 0, 0)
+				})
+			})
 		})
 	})
 
@@ -1459,6 +1528,9 @@ var _ = ginkgo.Describe("Topology validations", func() {
 			ginkgo.Entry("valid Topology",
 				testing.MakeDefaultOneLevelTopology("valid"),
 				gomega.Succeed()),
+			ginkgo.Entry("no levels",
+				testing.MakeTopology("no-levels").Obj(),
+				testing.BeInvalidError()),
 			ginkgo.Entry("invalid levels",
 				testing.MakeTopology("invalid-level").Levels("@invalid").Obj(),
 				testing.BeInvalidError()),
diff --git a/test/util/e2e.go b/test/util/e2e.go
index c937d630e..c97350af7 100644
--- a/test/util/e2e.go
+++ b/test/util/e2e.go
@@ -322,6 +322,6 @@ func CreateNamespaceFromPrefixWithLog(ctx context.Context, k8sClient client.Clie
 
 func CreateNamespaceFromObjectWithLog(ctx context.Context, k8sClient client.Client, ns *corev1.Namespace) *corev1.Namespace {
 	MustCreate(ctx, k8sClient, ns)
-	ginkgo.GinkgoLogr.Info(fmt.Sprintf("Created namespace: %s", ns.Name))
+	ginkgo.GinkgoLogr.Info("Created namespace", "namespace", ns.Name)
 	return ns
 }
diff --git a/test/util/util.go b/test/util/util.go
index 9fa1c341b..a9ddfa81d 100644
--- a/test/util/util.go
+++ b/test/util/util.go
@@ -47,6 +47,7 @@ import (
 	apimeta "k8s.io/apimachinery/pkg/api/meta"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/labels"
+	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/sets"
 	"k8s.io/apimachinery/pkg/watch"
@@ -715,7 +716,7 @@ func SetAdmissionCheckActive(ctx context.Context, k8sClient client.Client, admis
 	}, Timeout, Interval).Should(gomega.Succeed())
 }
 
-func SetWorkloadsAdmissionCheck(ctx context.Context, k8sClient client.Client, wl *kueue.Workload, check string, state kueue.CheckState, expectExisting bool) {
+func SetWorkloadsAdmissionCheck(ctx context.Context, k8sClient client.Client, wl *kueue.Workload, check kueue.AdmissionCheckReference, state kueue.CheckState, expectExisting bool) {
 	var updatedWorkload kueue.Workload
 	gomega.EventuallyWithOffset(1, func(g gomega.Gomega) {
 		g.Expect(k8sClient.Get(ctx, client.ObjectKeyFromObject(wl), &updatedWorkload)).To(gomega.Succeed())
@@ -1040,3 +1041,9 @@ func MustCreate(ctx context.Context, c client.Client, obj client.Object) {
 	ginkgo.GinkgoHelper()
 	gomega.ExpectWithOffset(1, c.Create(ctx, obj)).Should(gomega.Succeed())
 }
+
+func MustHaveOwnerReference(g gomega.Gomega, ownerRefs []metav1.OwnerReference, obj client.Object, scheme *runtime.Scheme) {
+	hasOwnerRef, err := controllerutil.HasOwnerReference(ownerRefs, obj, scheme)
+	g.Expect(err).ToNot(gomega.HaveOccurred())
+	g.Expect(hasOwnerRef).To(gomega.BeTrue())
+}