Repository: kubernetes-sigs/gateway-api

Issue:
BackendTLSPolicy conformance test for PolicyAncestorStatus

Add a conformance test to ensure consistent handling of PolicyAncestorStatus and policy acceptance logic across implementations. 

Proposed Test Cases:
- [ ] Conflict resolution between multiple BackendTLSPolicy resources targeting the same Service / Section. #4043
- [ ] Verify that controllers do not update PolicyAncestorStatus if the controllerName differs from their own.
- [x] Ensure that the AncestorRef field in PolicyAncestorStatus correctly points to a Gateway resource. Covered by #3930

Discussion:
@snorwin: /assign @snorwin 

Solution patch:
diff --git a/.github/workflows/crd-validation.yml b/.github/workflows/crd-validation.yml
new file mode 100644
index 00000000..4aa88c5a
--- /dev/null
+++ b/.github/workflows/crd-validation.yml
@@ -0,0 +1,32 @@
+name: CRD Validation
+
+on:
+  pull_request:
+    types: [opened, edited, synchronize, reopened]
+
+# Remove all permissions from GITHUB_TOKEN except metadata.
+permissions: {}
+
+jobs:
+  crd-validation:
+    name: CEL
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        # Available versions at https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/HEAD/envtest-releases.yaml
+        k8s_version: [v1.33.0, v1.32.0, v1.31.0, v1.30.3, v1.29.5]
+        crd_channel: [standard, experimental]
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
+        with:
+          persist-credentials: false
+      - name: Set up Go
+        uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # tag=v5.5.0
+      - name: Run CRD Validation tests
+        env:
+          K8S_VERSION: ${{ matrix.k8s_version }}
+          CRD_CHANNEL: ${{ matrix.crd_channel }}
+        run: |
+          make CEL_TEST_K8S_VERSION="${K8S_VERSION}" CEL_TEST_CRD_CHANNEL="${CRD_CHANNEL}" test.crds-validation
diff --git a/.github/workflows/kal.yml b/.github/workflows/kal.yml
index d657969f..618256e8 100644
--- a/.github/workflows/kal.yml
+++ b/.github/workflows/kal.yml
@@ -15,6 +15,9 @@ jobs:
       fail-fast: false
     steps:
       - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # tag=v4.2.2
+        name: Checkout code
+        with:
+          persist-credentials: false
       - name: Set up Go
         uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # tag=v5.5.0
       - name: Install Golang CI Lint
diff --git a/.golangci-kal.yml b/.golangci-kal.yml
index aad23ab4..27fdabbe 100644
--- a/.golangci-kal.yml
+++ b/.golangci-kal.yml
@@ -16,6 +16,8 @@ linters:
               - "nofloats" # Ensure floats are not used.
               - "nomaps" # Ensure maps are not used.
               - "nophase" # Phase fields are discouraged by the Kube API conventions, use conditions instead.
+              - "optionalorrequired" # Every field should be marked as `+optional` or `+required`.
+              - "ssatags" # Ensure proper Server-Side Apply (SSA) tags on array fields.
               - "statussubresource" # All root objects that have a `status` field should have a status subresource.
               - "uniquemarkers" # Ensure that types and fields do not contain more than a single definition of a marker that should only be present once.
             disable:
diff --git a/Makefile b/Makefile
index 8328ea21..3f2fee41 100644
--- a/Makefile
+++ b/Makefile
@@ -54,6 +54,10 @@ ROOT := $(abspath $(TOP))
 CONFORMANCE_FLAGS ?=
 GO_TEST_FLAGS ?=
 
+# Flags for CRD validation tests
+CEL_TEST_K8S_VERSION ?= 
+CEL_TEST_CRD_CHANNEL ?= standard
+
 all: generate vet fmt verify test
 
 # Run generators for protos, Deepcopy funcs, CRDs, and docs.
@@ -85,7 +89,8 @@ test:
 # Run tests for CRDs validation
 .PHONY: test.crds-validation
 test.crds-validation:
-	./hack/test-crds-validation.sh $(VERSION)
+	K8S_VERSION=$(CEL_TEST_K8S_VERSION) CRD_CHANNEL=$(CEL_TEST_CRD_CHANNEL) go test ${GO_TEST_FLAGS} -count=1 -timeout=120s --tags=$(CEL_TEST_CRD_CHANNEL) -v ./pkg/test/cel
+	K8S_VERSION=$(CEL_TEST_K8S_VERSION) CRD_CHANNEL=$(CEL_TEST_CRD_CHANNEL) go test ${GO_TEST_FLAGS} -count=1 -timeout=120s -v ./pkg/test/crd
 
 # Run conformance tests against controller implementation
 .PHONY: conformance
diff --git a/RELEASE_MANAGEMENT.md b/RELEASE_MANAGEMENT.md
index 94e2c724..78d00208 100644
--- a/RELEASE_MANAGEMENT.md
+++ b/RELEASE_MANAGEMENT.md
@@ -113,3 +113,19 @@ final release when it is cut.
 
 [Release Cycle]:https://gateway-api.sigs.k8s.io/contributing/release-cycle/
 [Milestone]:#github-milestone
+
+## Time Extensions
+
+Extensions to timelines may be requested by contributors. Our guidelines for
+this are based on the Kubernetes process:
+
+* Extensions can be granted on a per-GEP basis
+  * The owners of the GEP have to ask and provide a timeline (measured in
+    days) as to when they believe the GEP will be ready for merge.
+* The request and approval for a GEP extension needs to be in public.
+* Extensions can only be granted with a majority agreement by maintainers
+  / release-managers
+
+For our purposes we use GitHub discussions as the public place for
+requesting/approving extensions. Contributors should use an existing
+discussion for the release when feasible, otherwise create a discussion.
diff --git a/apis/v1/gateway_types.go b/apis/v1/gateway_types.go
index f54e5d10..86de1bad 100644
--- a/apis/v1/gateway_types.go
+++ b/apis/v1/gateway_types.go
@@ -33,15 +33,18 @@ import (
 // Gateway represents an instance of a service-traffic handling infrastructure
 // by binding Listeners to a set of IP addresses.
 type Gateway struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of Gateway.
+	// +required
 	Spec GatewaySpec `json:"spec"`
 
 	// Status defines the current state of Gateway.
 	//
 	// +kubebuilder:default={conditions: {{type: "Accepted", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"},{type: "Programmed", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}}
+	// +optional
 	Status GatewayStatus `json:"status,omitempty"`
 }
 
@@ -63,6 +66,7 @@ type GatewayList struct {
 type GatewaySpec struct {
 	// GatewayClassName used for this Gateway. This is the name of a
 	// GatewayClass resource.
+	// +required
 	GatewayClassName ObjectName `json:"gatewayClassName"`
 
 	// Listeners associated with this Gateway. Listeners define
@@ -236,6 +240,7 @@ type GatewaySpec struct {
 	// +kubebuilder:validation:XValidation:message="hostname must not be specified for protocols ['TCP', 'UDP']",rule="self.all(l, l.protocol in ['TCP', 'UDP']  ? (!has(l.hostname) || l.hostname == '') : true)"
 	// +kubebuilder:validation:XValidation:message="Listener name must be unique within the Gateway",rule="self.all(l1, self.exists_one(l2, l1.name == l2.name))"
 	// +kubebuilder:validation:XValidation:message="Combination of port, protocol and hostname must be unique for each listener",rule="self.all(l1, self.exists_one(l2, l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))"
+	// +required
 	Listeners []Listener `json:"listeners"`
 
 	// Addresses requested for this Gateway. This is optional and behavior can
@@ -260,6 +265,7 @@ type GatewaySpec struct {
 	// Support: Extended
 	//
 	// +optional
+	// +listType=atomic
 	// <gateway:validateIPAddress>
 	// +kubebuilder:validation:MaxItems=16
 	// +kubebuilder:validation:XValidation:message="IPAddress values must be unique",rule="self.all(a1, a1.type == 'IPAddress' ? self.exists_one(a2, a2.type == a1.type && a2.value == a1.value) : true )"
@@ -333,6 +339,7 @@ type Listener struct {
 	// Gateway.
 	//
 	// Support: Core
+	// +required
 	Name SectionName `json:"name"`
 
 	// Hostname specifies the virtual hostname to match for protocol types that
@@ -390,11 +397,17 @@ type Listener struct {
 	// same port, subject to the Listener compatibility rules.
 	//
 	// Support: Core
+	//
+	// +kubebuilder:validation:Minimum=1
+	// +kubebuilder:validation:Maximum=65535
+	//
+	// +required
 	Port PortNumber `json:"port"`
 
 	// Protocol specifies the network protocol this listener expects to receive.
 	//
 	// Support: Core
+	// +required
 	Protocol ProtocolType `json:"protocol"`
 
 	// TLS is the TLS configuration for the Listener. This field is required if
@@ -561,6 +574,7 @@ type GatewayTLSConfig struct {
 	// Support: Implementation-specific (More than one reference or other resource types)
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=64
 	CertificateRefs []SecretObjectReference `json:"certificateRefs,omitempty"`
 
@@ -635,6 +649,8 @@ type FrontendTLSValidation struct {
 	// "ResolvedRefs" condition MUST be set to False for this listener with the
 	// "RefNotPermitted" reason.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=8
 	// +kubebuilder:validation:MinItems=1
 	CACertificateRefs []ObjectReference `json:"caCertificateRefs,omitempty"`
@@ -648,6 +664,7 @@ type AllowedRoutes struct {
 	// Support: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:default={from: Same}
 	Namespaces *RouteNamespaces `json:"namespaces,omitempty"`
 
@@ -664,6 +681,7 @@ type AllowedRoutes struct {
 	// Support: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=8
 	Kinds []RouteGroupKind `json:"kinds,omitempty"`
 }
@@ -721,6 +739,7 @@ type RouteGroupKind struct {
 	Group *Group `json:"group,omitempty"`
 
 	// Kind is the kind of the Route.
+	// +required
 	Kind Kind `json:"kind"`
 }
 
@@ -764,6 +783,7 @@ type GatewayStatusAddress struct {
 	//
 	// +kubebuilder:validation:MinLength=1
 	// +kubebuilder:validation:MaxLength=253
+	// +required
 	Value string `json:"value"`
 }
 
@@ -780,6 +800,7 @@ type GatewayStatus struct {
 	//   * a specified address was unusable (e.g. already in use)
 	//
 	// +optional
+	// +listType=atomic
 	// <gateway:validateIPAddress>
 	// +kubebuilder:validation:MaxItems=16
 	Addresses []GatewayStatusAddress `json:"addresses,omitempty"`
@@ -873,15 +894,18 @@ type GatewayInfrastructure struct {
 // configuration resource within the namespace.
 type LocalParametersReference struct {
 	// Group is the group of the referent.
+	// +required
 	Group Group `json:"group"`
 
 	// Kind is kind of the referent.
+	// +required
 	Kind Kind `json:"kind"`
 
 	// Name is the name of the referent.
 	//
 	// +kubebuilder:validation:MinLength=1
 	// +kubebuilder:validation:MaxLength=253
+	// +required
 	Name string `json:"name"`
 }
 
@@ -1096,6 +1120,7 @@ const (
 // ListenerStatus is the status associated with a Listener.
 type ListenerStatus struct {
 	// Name is the name of the Listener that this status corresponds to.
+	// +required
 	Name SectionName `json:"name"`
 
 	// SupportedKinds is the list indicating the Kinds supported by this
@@ -1108,6 +1133,8 @@ type ListenerStatus struct {
 	// and invalid Route kinds are specified, the implementation MUST
 	// reference the valid Route kinds that have been specified.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=8
 	SupportedKinds []RouteGroupKind `json:"supportedKinds"`
 
@@ -1128,6 +1155,7 @@ type ListenerStatus struct {
 	//
 	// Uses for this field include troubleshooting Route attachment and
 	// measuring blast radius/impact of changes to a Listener.
+	// +required
 	AttachedRoutes int32 `json:"attachedRoutes"`
 
 	// Conditions describe the current condition of this listener.
@@ -1135,6 +1163,7 @@ type ListenerStatus struct {
 	// +listType=map
 	// +listMapKey=type
 	// +kubebuilder:validation:MaxItems=8
+	// +required
 	Conditions []metav1.Condition `json:"conditions"`
 }
 
diff --git a/apis/v1/gatewayclass_types.go b/apis/v1/gatewayclass_types.go
index 6699e7a1..655195ce 100644
--- a/apis/v1/gatewayclass_types.go
+++ b/apis/v1/gatewayclass_types.go
@@ -49,10 +49,12 @@ import (
 //
 // GatewayClass is a Cluster level resource.
 type GatewayClass struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of GatewayClass.
+	// +required
 	Spec GatewayClassSpec `json:"spec"`
 
 	// Status defines the current state of GatewayClass.
@@ -61,6 +63,7 @@ type GatewayClass struct {
 	// specify their controller name.
 	//
 	// +kubebuilder:default={conditions: {{type: "Accepted", status: "Unknown", message: "Waiting for controller", reason: "Pending", lastTransitionTime: "1970-01-01T00:00:00Z"}}}
+	// +optional
 	Status GatewayClassStatus `json:"status,omitempty"`
 }
 
@@ -83,6 +86,7 @@ type GatewayClassSpec struct {
 	// Support: Core
 	//
 	// +kubebuilder:validation:XValidation:message="Value is immutable",rule="self == oldSelf"
+	// +required
 	ControllerName GatewayController `json:"controllerName"`
 
 	// ParametersRef is a reference to a resource that contains the configuration
@@ -118,15 +122,18 @@ type GatewayClassSpec struct {
 // configuration resource within the cluster.
 type ParametersReference struct {
 	// Group is the group of the referent.
+	// +required
 	Group Group `json:"group"`
 
 	// Kind is kind of the referent.
+	// +required
 	Kind Kind `json:"kind"`
 
 	// Name is the name of the referent.
 	//
 	// +kubebuilder:validation:MinLength=1
 	// +kubebuilder:validation:MaxLength=253
+	// +required
 	Name string `json:"name"`
 
 	// Namespace is the namespace of the referent.
@@ -287,5 +294,6 @@ type GatewayClassList struct {
 type FeatureName string
 
 type SupportedFeature struct {
+	// +required
 	Name FeatureName `json:"name"`
 }
diff --git a/apis/v1/gatewayclass_types_overrides.go b/apis/v1/gatewayclass_types_overrides.go
index f6350847..8d768fde 100644
--- a/apis/v1/gatewayclass_types_overrides.go
+++ b/apis/v1/gatewayclass_types_overrides.go
@@ -51,6 +51,7 @@ func (s *SupportedFeature) UnmarshalJSON(data []byte) error {
 // This is solely for the purpose of ensuring backward compatibility and
 // SHOULD NOT be used elsewhere.
 type supportedFeatureInternal struct {
+	// +required
 	Name FeatureName `json:"name"`
 }
 
diff --git a/apis/v1/grpcroute_types.go b/apis/v1/grpcroute_types.go
index c6eeb0f3..5f9bde7a 100644
--- a/apis/v1/grpcroute_types.go
+++ b/apis/v1/grpcroute_types.go
@@ -56,13 +56,16 @@ import (
 // Implementations MAY also accept HTTP/2 connections with an upgrade from
 // HTTP/1, i.e. without prior knowledge.
 type GRPCRoute struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of GRPCRoute.
+	// +required
 	Spec GRPCRouteSpec `json:"spec,omitempty"`
 
 	// Status defines the current state of GRPCRoute.
+	// +optional
 	Status GRPCRouteStatus `json:"status,omitempty"`
 }
 
@@ -136,12 +139,14 @@ type GRPCRouteSpec struct {
 	// Support: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	Hostnames []Hostname `json:"hostnames,omitempty"`
 
 	// Rules are a list of GRPC matchers, filters and actions.
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	// +kubebuilder:validation:XValidation:message="While 16 rules and 64 matches per rule are allowed, the total number of matches across all rules in a route must be less than 128",rule="(self.size() > 0 ? (has(self[0].matches) ? self[0].matches.size() : 0) : 0) + (self.size() > 1 ? (has(self[1].matches) ? self[1].matches.size() : 0) : 0) + (self.size() > 2 ? (has(self[2].matches) ? self[2].matches.size() : 0) : 0) + (self.size() > 3 ? (has(self[3].matches) ? self[3].matches.size() : 0) : 0) + (self.size() > 4 ? (has(self[4].matches) ? self[4].matches.size() : 0) : 0) + (self.size() > 5 ? (has(self[5].matches) ? self[5].matches.size() : 0) : 0) + (self.size() > 6 ? (has(self[6].matches) ? self[6].matches.size() : 0) : 0) + (self.size() > 7 ? (has(self[7].matches) ? self[7].matches.size() : 0) : 0) + (self.size() > 8 ? (has(self[8].matches) ? self[8].matches.size() : 0) : 0) + (self.size() > 9 ? (has(self[9].matches) ? self[9].matches.size() : 0) : 0) + (self.size() > 10 ? (has(self[10].matches) ? self[10].matches.size() : 0) : 0) + (self.size() > 11 ? (has(self[11].matches) ? self[11].matches.size() : 0) : 0) + (self.size() > 12 ? (has(self[12].matches) ? self[12].matches.size() : 0) : 0) + (self.size() > 13 ? (has(self[13].matches) ? self[13].matches.size() : 0) : 0) + (self.size() > 14 ? (has(self[14].matches) ? self[14].matches.size() : 0) : 0) + (self.size() > 15 ? (has(self[15].matches) ? self[15].matches.size() : 0) : 0) <= 128"
 	// <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))">
@@ -209,6 +214,7 @@ type GRPCRouteRule struct {
 	// the above criteria.
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=64
 	Matches []GRPCRouteMatch `json:"matches,omitempty"`
 
@@ -238,6 +244,7 @@ type GRPCRouteRule struct {
 	// Support: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	// +kubebuilder:validation:XValidation:message="RequestHeaderModifier filter cannot be repeated",rule="self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
 	// +kubebuilder:validation:XValidation:message="ResponseHeaderModifier filter cannot be repeated",rule="self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1"
@@ -273,6 +280,7 @@ type GRPCRouteRule struct {
 	// Support for weight: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	BackendRefs []GRPCBackendRef `json:"backendRefs,omitempty"`
 
@@ -404,12 +412,14 @@ type GRPCHeaderMatch struct {
 	// entries with an equivalent header name MUST be ignored. Due to the
 	// case-insensitivity of header names, "foo" and "Foo" are considered
 	// equivalent.
+	// +required
 	Name GRPCHeaderName `json:"name"`
 
 	// Value is the value of the gRPC Header to be matched.
 	//
 	// +kubebuilder:validation:MinLength=1
 	// +kubebuilder:validation:MaxLength=4096
+	// +required
 	Value string `json:"value"`
 }
 
@@ -520,6 +530,7 @@ type GRPCRouteFilter struct {
 	// +unionDiscriminator
 	// +kubebuilder:validation:Enum=ResponseHeaderModifier;RequestHeaderModifier;RequestMirror;ExtensionRef
 	// <gateway:experimental:validation:Enum=ResponseHeaderModifier;RequestHeaderModifier;RequestMirror;ExtensionRef>
+	// +required
 	Type GRPCRouteFilterType `json:"type"`
 
 	// RequestHeaderModifier defines a schema for a filter that modifies request
@@ -630,6 +641,7 @@ type GRPCBackendRef struct {
 	// Filters field in GRPCRouteRule.)
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	// +kubebuilder:validation:XValidation:message="RequestHeaderModifier filter cannot be repeated",rule="self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
 	// +kubebuilder:validation:XValidation:message="ResponseHeaderModifier filter cannot be repeated",rule="self.filter(f, f.type == 'ResponseHeaderModifier').size() <= 1"
diff --git a/apis/v1/httproute_types.go b/apis/v1/httproute_types.go
index 157932e9..39a01f27 100644
--- a/apis/v1/httproute_types.go
+++ b/apis/v1/httproute_types.go
@@ -33,13 +33,16 @@ import (
 // used to specify additional processing steps. Backends specify where matching
 // requests should be routed.
 type HTTPRoute struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of HTTPRoute.
+	// +required
 	Spec HTTPRouteSpec `json:"spec"`
 
 	// Status defines the current state of HTTPRoute.
+	// +optional
 	Status HTTPRouteStatus `json:"status,omitempty"`
 }
 
@@ -111,12 +114,14 @@ type HTTPRouteSpec struct {
 	// Support: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	Hostnames []Hostname `json:"hostnames,omitempty"`
 
 	// Rules are a list of HTTP matchers, filters and actions.
 	//
 	// +optional
+	// +listType=atomic
 	// <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))">
 	// +kubebuilder:validation:MaxItems=16
 	// +kubebuilder:default={{matches: {{path: {type: "PathPrefix", value: "/"}}}}}
@@ -198,6 +203,7 @@ type HTTPRouteRule struct {
 	// parent a request is coming from, a HTTP 404 status code MUST be returned.
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=64
 	// +kubebuilder:default={{path:{ type: "PathPrefix", value: "/"}}}
 	Matches []HTTPRouteMatch `json:"matches,omitempty"`
@@ -240,6 +246,7 @@ type HTTPRouteRule struct {
 	// Support: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	// +kubebuilder:validation:XValidation:message="May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both",rule="!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))"
 	// +kubebuilder:validation:XValidation:message="RequestHeaderModifier filter cannot be repeated",rule="self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
@@ -285,6 +292,7 @@ type HTTPRouteRule struct {
 	// Support for weight: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	BackendRefs []HTTPBackendRef `json:"backendRefs,omitempty"`
 
@@ -379,6 +387,7 @@ type HTTPRouteRetry struct {
 	// Support: Extended
 	//
 	// +optional
+	// +listType=atomic
 	Codes []HTTPRouteRetryStatusCode `json:"codes,omitempty"`
 
 	// Attempts specifies the maximum number of times an individual request
@@ -608,12 +617,14 @@ type HTTPHeaderMatch struct {
 	// Generally, proxies should follow the guidance from the RFC:
 	// https://www.rfc-editor.org/rfc/rfc7230.html#section-3.2.2 regarding
 	// processing a repeated header, with special handling for "Set-Cookie".
+	// +required
 	Name HTTPHeaderName `json:"name"`
 
 	// Value is the value of HTTP Header to be matched.
 	//
 	// +kubebuilder:validation:MinLength=1
 	// +kubebuilder:validation:MaxLength=4096
+	// +required
 	Value string `json:"value"`
 }
 
@@ -675,12 +686,14 @@ type HTTPQueryParamMatch struct {
 	//
 	// Users SHOULD NOT route traffic based on repeated query params to guard
 	// themselves against potential differences in the implementations.
+	// +required
 	Name HTTPHeaderName `json:"name"`
 
 	// Value is the value of HTTP query param to be matched.
 	//
 	// +kubebuilder:validation:MinLength=1
 	// +kubebuilder:validation:MaxLength=1024
+	// +required
 	Value string `json:"value"`
 }
 
@@ -830,6 +843,7 @@ type HTTPRouteFilter struct {
 	// +unionDiscriminator
 	// +kubebuilder:validation:Enum=RequestHeaderModifier;ResponseHeaderModifier;RequestMirror;RequestRedirect;URLRewrite;ExtensionRef
 	// <gateway:experimental:validation:Enum=RequestHeaderModifier;ResponseHeaderModifier;RequestMirror;RequestRedirect;URLRewrite;ExtensionRef;CORS>
+	// +required
 	Type HTTPRouteFilterType `json:"type"`
 
 	// RequestHeaderModifier defines a schema for a filter that modifies request
@@ -977,12 +991,14 @@ type HTTPHeader struct {
 	// with an equivalent header name MUST be ignored. Due to the
 	// case-insensitivity of header names, "foo" and "Foo" are considered
 	// equivalent.
+	// +required
 	Name HTTPHeaderName `json:"name"`
 
 	// Value is the value of HTTP Header to be matched.
 	//
 	// +kubebuilder:validation:MinLength=1
 	// +kubebuilder:validation:MaxLength=4096
+	// +required
 	Value string `json:"value"`
 }
 
@@ -1101,6 +1117,7 @@ type HTTPPathModifier struct {
 	// Reason of `UnsupportedValue`.
 	//
 	// +kubebuilder:validation:Enum=ReplaceFullPath;ReplacePrefixMatch
+	// +required
 	Type HTTPPathModifierType `json:"type"`
 
 	// ReplaceFullPath specifies the value with which to replace the full path
@@ -1208,6 +1225,9 @@ type HTTPRequestRedirectFilter struct {
 	// Support: Extended
 	//
 	// +optional
+	//
+	// +kubebuilder:validation:Minimum=1
+	// +kubebuilder:validation:Maximum=65535
 	Port *PortNumber `json:"port,omitempty"`
 
 	// StatusCode is the HTTP status code to be used in response.
@@ -1274,6 +1294,7 @@ type HTTPRequestMirrorFilter struct {
 	// Support: Extended for Kubernetes Service
 	//
 	// Support: Implementation-specific for any other resource
+	// +required
 	BackendRef BackendObjectReference `json:"backendRef"`
 
 	// Percent represents the percentage of requests that should be
@@ -1356,6 +1377,7 @@ type HTTPCORSFilter struct {
 	// Support: Extended
 	// +listType=set
 	// +kubebuilder:validation:MaxItems=64
+	// +optional
 	AllowOrigins []AbsoluteURI `json:"allowOrigins,omitempty"`
 
 	// AllowCredentials indicates whether the actual cross-origin request allows
@@ -1417,6 +1439,7 @@ type HTTPCORSFilter struct {
 	// +listType=set
 	// +kubebuilder:validation:MaxItems=9
 	// +kubebuilder:validation:XValidation:message="AllowMethods cannot contain '*' alongside other methods",rule="!('*' in self && self.size() > 1)"
+	// +optional
 	AllowMethods []HTTPMethodWithWildcard `json:"allowMethods,omitempty"`
 
 	// AllowHeaders indicates which HTTP request headers are supported for
@@ -1458,6 +1481,7 @@ type HTTPCORSFilter struct {
 	//
 	// +listType=set
 	// +kubebuilder:validation:MaxItems=64
+	// +optional
 	AllowHeaders []HTTPHeaderName `json:"allowHeaders,omitempty"`
 
 	// ExposeHeaders indicates which HTTP response headers can be exposed
@@ -1588,6 +1612,7 @@ type HTTPBackendRef struct {
 	// Filters field in HTTPRouteRule.)
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	// +kubebuilder:validation:XValidation:message="May specify either httpRouteFilterRequestRedirect or httpRouteFilterRequestRewrite, but not both",rule="!(self.exists(f, f.type == 'RequestRedirect') && self.exists(f, f.type == 'URLRewrite'))"
 	// +kubebuilder:validation:XValidation:message="RequestHeaderModifier filter cannot be repeated",rule="self.filter(f, f.type == 'RequestHeaderModifier').size() <= 1"
diff --git a/apis/v1/object_reference_types.go b/apis/v1/object_reference_types.go
index dd507b21..414e39b9 100644
--- a/apis/v1/object_reference_types.go
+++ b/apis/v1/object_reference_types.go
@@ -27,12 +27,15 @@ package v1
 type LocalObjectReference struct {
 	// Group is the group of the referent. For example, "gateway.networking.k8s.io".
 	// When unspecified or empty string, core API group is inferred.
+	// +required
 	Group Group `json:"group"`
 
 	// Kind is kind of the referent. For example "HTTPRoute" or "Service".
+	// +required
 	Kind Kind `json:"kind"`
 
 	// Name is the name of the referent.
+	// +required
 	Name ObjectName `json:"name"`
 }
 
@@ -60,6 +63,7 @@ type SecretObjectReference struct {
 	Kind *Kind `json:"kind"`
 
 	// Name is the name of the referent.
+	// +required
 	Name ObjectName `json:"name"`
 
 	// Namespace is the namespace of the referenced object. When unspecified, the local
@@ -121,6 +125,7 @@ type BackendObjectReference struct {
 	Kind *Kind `json:"kind,omitempty"`
 
 	// Name is the name of the referent.
+	// +required
 	Name ObjectName `json:"name"`
 
 	// Namespace is the namespace of the backend. When unspecified, the local
@@ -143,6 +148,8 @@ type BackendObjectReference struct {
 	// resource or this field.
 	//
 	// +optional
+	// +kubebuilder:validation:Minimum=1
+	// +kubebuilder:validation:Maximum=65535
 	Port *PortNumber `json:"port,omitempty"`
 }
 
@@ -157,12 +164,15 @@ type BackendObjectReference struct {
 type ObjectReference struct {
 	// Group is the group of the referent. For example, "gateway.networking.k8s.io".
 	// When set to the empty string, core API group is inferred.
+	// +required
 	Group Group `json:"group"`
 
 	// Kind is kind of the referent. For example "ConfigMap" or "Service".
+	// +required
 	Kind Kind `json:"kind"`
 
 	// Name is the name of the referent.
+	// +required
 	Name ObjectName `json:"name"`
 
 	// Namespace is the namespace of the referenced object. When unspecified, the local
diff --git a/apis/v1/shared_types.go b/apis/v1/shared_types.go
index 226c7763..b98a9e81 100644
--- a/apis/v1/shared_types.go
+++ b/apis/v1/shared_types.go
@@ -86,6 +86,7 @@ type ParentReference struct {
 	// Name is the name of the referent.
 	//
 	// Support: Core
+	// +required
 	Name ObjectName `json:"name"`
 
 	// SectionName is the name of a section within the target resource. In the
@@ -148,6 +149,9 @@ type ParentReference struct {
 	// Support: Extended
 	//
 	// +optional
+	//
+	// +kubebuilder:validation:Minimum=1
+	// +kubebuilder:validation:Maximum=65535
 	Port *PortNumber `json:"port,omitempty"`
 }
 
@@ -218,6 +222,7 @@ type CommonRouteSpec struct {
 	// </gateway:experimental:description>
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=32
 	// <gateway:standard:validation:XValidation:message="sectionName must be specified when parentRefs includes 2 or more references to the same parent",rule="self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))">
 	// <gateway:standard:validation:XValidation:message="sectionName must be unique when parentRefs includes 2 or more references to the same parent",rule="self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))">
@@ -227,9 +232,6 @@ type CommonRouteSpec struct {
 }
 
 // PortNumber defines a network port.
-//
-// +kubebuilder:validation:Minimum=1
-// +kubebuilder:validation:Maximum=65535
 type PortNumber int32
 
 // BackendRef defines how a Route should forward a request to a Kubernetes
@@ -436,6 +438,7 @@ const (
 type RouteParentStatus struct {
 	// ParentRef corresponds with a ParentRef in the spec that this
 	// RouteParentStatus struct describes the status of.
+	// +required
 	ParentRef ParentReference `json:"parentRef"`
 
 	// ControllerName is a domain/path string that indicates the name of the
@@ -451,6 +454,7 @@ type RouteParentStatus struct {
 	// Controllers MUST populate this field when writing status. Controllers should ensure that
 	// entries to status populated with their ControllerName are cleaned up when they are no
 	// longer necessary.
+	// +required
 	ControllerName GatewayController `json:"controllerName"`
 
 	// Conditions describes the status of the route with respect to the Gateway.
@@ -477,6 +481,7 @@ type RouteParentStatus struct {
 	// +listMapKey=type
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=8
+	// +required
 	Conditions []metav1.Condition `json:"conditions,omitempty"`
 }
 
@@ -498,6 +503,8 @@ type RouteStatus struct {
 	// A maximum of 32 Gateways will be represented in this list. An empty list
 	// means the route has not been attached to any Gateway.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=32
 	Parents []RouteParentStatus `json:"parents"`
 }
@@ -913,6 +920,7 @@ const (
 // +kubebuilder:validation:XValidation:message="numerator must be less than or equal to denominator",rule="self.numerator <= self.denominator"
 type Fraction struct {
 	// +kubebuilder:validation:Minimum=0
+	// +required
 	Numerator int32 `json:"numerator"`
 
 	// +optional
diff --git a/apis/v1alpha2/policy_types.go b/apis/v1alpha2/policy_types.go
index bc2ef766..dc2f8f7f 100644
--- a/apis/v1alpha2/policy_types.go
+++ b/apis/v1alpha2/policy_types.go
@@ -38,12 +38,15 @@ const (
 // the policy attachment documentation for Gateway API.
 type LocalPolicyTargetReference struct {
 	// Group is the group of the target resource.
+	// +required
 	Group Group `json:"group"`
 
 	// Kind is kind of the target resource.
+	// +required
 	Kind Kind `json:"kind"`
 
 	// Name is the name of the target resource.
+	// +required
 	Name ObjectName `json:"name"`
 }
 
@@ -55,12 +58,15 @@ type LocalPolicyTargetReference struct {
 // documentation for Gateway API.
 type NamespacedPolicyTargetReference struct {
 	// Group is the group of the target resource.
+	// +required
 	Group Group `json:"group"`
 
 	// Kind is kind of the target resource.
+	// +required
 	Kind Kind `json:"kind"`
 
 	// Name is the name of the target resource.
+	// +required
 	Name ObjectName `json:"name"`
 
 	// Namespace is the namespace of the referent. When unspecified, the local
@@ -174,6 +180,7 @@ const (
 type PolicyAncestorStatus struct {
 	// AncestorRef corresponds with a ParentRef in the spec that this
 	// PolicyAncestorStatus struct describes the status of.
+	// +required
 	AncestorRef ParentReference `json:"ancestorRef"`
 
 	// ControllerName is a domain/path string that indicates the name of the
@@ -189,10 +196,12 @@ type PolicyAncestorStatus struct {
 	// Controllers MUST populate this field when writing status. Controllers should ensure that
 	// entries to status populated with their ControllerName are cleaned up when they are no
 	// longer necessary.
+	// +required
 	ControllerName GatewayController `json:"controllerName"`
 
 	// Conditions describes the status of the Policy with respect to the given Ancestor.
 	//
+	// +required
 	// +listType=map
 	// +listMapKey=type
 	// +kubebuilder:validation:MinItems=1
@@ -233,6 +242,8 @@ type PolicyStatus struct {
 	// additional Gateways would be able to reference the Service targeted by
 	// the BackendTLSPolicy.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	Ancestors []PolicyAncestorStatus `json:"ancestors"`
 }
diff --git a/apis/v1alpha2/shared_types.go b/apis/v1alpha2/shared_types.go
index 2fb84d5f..3d2f7879 100644
--- a/apis/v1alpha2/shared_types.go
+++ b/apis/v1alpha2/shared_types.go
@@ -40,9 +40,6 @@ type ParentReference = v1.ParentReference
 type CommonRouteSpec = v1.CommonRouteSpec
 
 // PortNumber defines a network port.
-//
-// +kubebuilder:validation:Minimum=1
-// +kubebuilder:validation:Maximum=65535
 type PortNumber = v1.PortNumber
 
 // BackendRef defines how a Route should forward a request to a Kubernetes
diff --git a/apis/v1alpha2/tcproute_types.go b/apis/v1alpha2/tcproute_types.go
index e383af49..e545e6fd 100644
--- a/apis/v1alpha2/tcproute_types.go
+++ b/apis/v1alpha2/tcproute_types.go
@@ -31,13 +31,16 @@ import (
 // listener, it can be used to forward connections on the port specified by the
 // listener to a set of backends specified by the TCPRoute.
 type TCPRoute struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of TCPRoute.
+	// +required
 	Spec TCPRouteSpec `json:"spec"`
 
 	// Status defines the current state of TCPRoute.
+	// +optional
 	Status TCPRouteStatus `json:"status,omitempty"`
 }
 
@@ -47,6 +50,8 @@ type TCPRouteSpec struct {
 
 	// Rules are a list of TCP matchers and actions.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	// <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))">
@@ -81,6 +86,8 @@ type TCPRouteRule struct {
 	//
 	// Support for weight: Extended
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	BackendRefs []BackendRef `json:"backendRefs,omitempty"`
diff --git a/apis/v1alpha2/tlsroute_types.go b/apis/v1alpha2/tlsroute_types.go
index f1b3814c..8ca02d37 100644
--- a/apis/v1alpha2/tlsroute_types.go
+++ b/apis/v1alpha2/tlsroute_types.go
@@ -33,13 +33,16 @@ import (
 // If you need to forward traffic to a single target for a TLS listener, you
 // could choose to use a TCPRoute with a TLS listener.
 type TLSRoute struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of TLSRoute.
+	// +required
 	Spec TLSRouteSpec `json:"spec"`
 
 	// Status defines the current state of TLSRoute.
+	// +optional
 	Status TLSRouteStatus `json:"status,omitempty"`
 }
 
@@ -82,11 +85,14 @@ type TLSRouteSpec struct {
 	// Support: Core
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=16
 	Hostnames []Hostname `json:"hostnames,omitempty"`
 
 	// Rules are a list of TLS matchers and actions.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	// <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))">
@@ -124,6 +130,8 @@ type TLSRouteRule struct {
 	//
 	// Support for weight: Extended
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	BackendRefs []BackendRef `json:"backendRefs,omitempty"`
diff --git a/apis/v1alpha2/udproute_types.go b/apis/v1alpha2/udproute_types.go
index c7e92b92..f5f8feff 100644
--- a/apis/v1alpha2/udproute_types.go
+++ b/apis/v1alpha2/udproute_types.go
@@ -31,13 +31,16 @@ import (
 // listener, it can be used to forward traffic on the port specified by the
 // listener to a set of backends specified by the UDPRoute.
 type UDPRoute struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of UDPRoute.
+	// +required
 	Spec UDPRouteSpec `json:"spec"`
 
 	// Status defines the current state of UDPRoute.
+	// +optional
 	Status UDPRouteStatus `json:"status,omitempty"`
 }
 
@@ -47,6 +50,8 @@ type UDPRouteSpec struct {
 
 	// Rules are a list of UDP matchers and actions.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	// <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))">
@@ -81,6 +86,8 @@ type UDPRouteRule struct {
 	//
 	// Support for weight: Extended
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	BackendRefs []BackendRef `json:"backendRefs,omitempty"`
diff --git a/apis/v1alpha3/backendtlspolicy_types.go b/apis/v1alpha3/backendtlspolicy_types.go
index 75655f5d..e0049190 100644
--- a/apis/v1alpha3/backendtlspolicy_types.go
+++ b/apis/v1alpha3/backendtlspolicy_types.go
@@ -36,13 +36,16 @@ import (
 // BackendTLSPolicy provides a way to configure how a Gateway
 // connects to a Backend via TLS.
 type BackendTLSPolicy struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of BackendTLSPolicy.
+	// +required
 	Spec BackendTLSPolicySpec `json:"spec"`
 
 	// Status defines the current state of BackendTLSPolicy.
+	// +optional
 	Status v1alpha2.PolicyStatus `json:"status,omitempty"`
 }
 
@@ -77,6 +80,8 @@ type BackendTLSPolicySpec struct {
 	//
 	// Support: Implementation-specific for any other resource
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	// +kubebuilder:validation:XValidation:message="sectionName must be specified when targetRefs includes 2 or more references to the same target",rule="self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))"
@@ -84,6 +89,7 @@ type BackendTLSPolicySpec struct {
 	TargetRefs []v1alpha2.LocalPolicyTargetReferenceWithSectionName `json:"targetRefs"`
 
 	// Validation contains backend TLS validation configuration.
+	// +required
 	Validation BackendTLSPolicyValidation `json:"validation"`
 
 	// Options are a list of key/value pairs to enable extended TLS
@@ -128,8 +134,9 @@ type BackendTLSPolicyValidation struct {
 	// Support: Implementation-specific (More than one reference, or other kinds
 	// of resources).
 	//
-	// +kubebuilder:validation:MaxItems=8
 	// +optional
+	// +listType=atomic
+	// +kubebuilder:validation:MaxItems=8
 	CACertificateRefs []v1.LocalObjectReference `json:"caCertificateRefs,omitempty"`
 
 	// WellKnownCACertificates specifies whether system CA certificates may be used in
@@ -145,6 +152,7 @@ type BackendTLSPolicyValidation struct {
 	// Support: Implementation-specific
 	//
 	// +optional
+	// +listType=atomic
 	WellKnownCACertificates *WellKnownCACertificatesType `json:"wellKnownCACertificates,omitempty"`
 
 	// Hostname is used for two purposes in the connection between Gateways and
@@ -154,6 +162,8 @@ type BackendTLSPolicyValidation struct {
 	// 2. Hostname MUST be used for authentication and MUST match the certificate served by the matching backend, unless SubjectAltNames is specified.
 	//
 	// Support: Core
+	//
+	// +required
 	Hostname v1.PreciseHostname `json:"hostname"`
 
 	// SubjectAltNames contains one or more Subject Alternative Names.
@@ -163,6 +173,7 @@ type BackendTLSPolicyValidation struct {
 	// Support: Extended
 	//
 	// +optional
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=5
 	SubjectAltNames []SubjectAltName `json:"subjectAltNames,omitempty"`
 }
@@ -176,6 +187,8 @@ type SubjectAltName struct {
 	// Type determines the format of the Subject Alternative Name. Always required.
 	//
 	// Support: Core
+	//
+	// +required
 	Type SubjectAltNameType `json:"type"`
 
 	// Hostname contains Subject Alternative Name specified in DNS name format.
diff --git a/apis/v1alpha3/tlsroute_types.go b/apis/v1alpha3/tlsroute_types.go
index 82345f90..8ae5b518 100644
--- a/apis/v1alpha3/tlsroute_types.go
+++ b/apis/v1alpha3/tlsroute_types.go
@@ -36,13 +36,16 @@ import (
 // If you need to forward traffic to a single target for a TLS listener, you
 // could choose to use a TCPRoute with a TLS listener.
 type TLSRoute struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of TLSRoute.
+	// +required
 	Spec TLSRouteSpec `json:"spec"`
 
 	// Status defines the current state of TLSRoute.
+	// +optional
 	Status v1alpha2.TLSRouteStatus `json:"status,omitempty"`
 }
 
@@ -84,17 +87,20 @@ type TLSRouteSpec struct {
 	//
 	// Support: Core
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
-	// +required
 	Hostnames []Hostname `json:"hostnames,omitempty"`
 
-	// Rules are a list of TLS matchers and actions.
+	// Rules are a list of actions.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
-	// +kubebuilder:validation:MaxItems=16
+	// +kubebuilder:validation:MaxItems=1
 	// <gateway:experimental:validation:XValidation:message="Rule name must be unique within the route",rule="self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))">
-	Rules []v1alpha2.TLSRouteRule `json:"rules"`
+	Rules []v1alpha2.TLSRouteRule `json:"rules,omitempty"`
 }
 
 // +kubebuilder:object:root=true
diff --git a/apis/v1beta1/referencegrant_types.go b/apis/v1beta1/referencegrant_types.go
index 0b0caf70..bed43bc9 100644
--- a/apis/v1beta1/referencegrant_types.go
+++ b/apis/v1beta1/referencegrant_types.go
@@ -41,10 +41,12 @@ import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 // no grant, and MUST respond to the removal of a grant by revoking the access
 // that the grant allowed.
 type ReferenceGrant struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of ReferenceGrant.
+	// +optional
 	Spec ReferenceGrantSpec `json:"spec,omitempty"`
 
 	// Note that `Status` sub-resource has been excluded at the
@@ -70,6 +72,8 @@ type ReferenceGrantSpec struct {
 	//
 	// Support: Core
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	From []ReferenceGrantFrom `json:"from"`
@@ -81,6 +85,8 @@ type ReferenceGrantSpec struct {
 	//
 	// Support: Core
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
 	To []ReferenceGrantTo `json:"to"`
@@ -92,6 +98,8 @@ type ReferenceGrantFrom struct {
 	// When empty, the Kubernetes core API group is inferred.
 	//
 	// Support: Core
+	//
+	// +required
 	Group Group `json:"group"`
 
 	// Kind is the kind of the referent. Although implementations may support
@@ -109,11 +117,14 @@ type ReferenceGrantFrom struct {
 	// * TCPRoute
 	// * TLSRoute
 	// * UDPRoute
+	// +required
 	Kind Kind `json:"kind"`
 
 	// Namespace is the namespace of the referent.
 	//
 	// Support: Core
+	//
+	// +required
 	Namespace Namespace `json:"namespace"`
 }
 
@@ -124,6 +135,8 @@ type ReferenceGrantTo struct {
 	// When empty, the Kubernetes core API group is inferred.
 	//
 	// Support: Core
+	//
+	// +required
 	Group Group `json:"group"`
 
 	// Kind is the kind of the referent. Although implementations may support
@@ -132,6 +145,8 @@ type ReferenceGrantTo struct {
 	//
 	// * Secret when used to permit a SecretObjectReference
 	// * Service when used to permit a BackendObjectReference
+	//
+	// +required
 	Kind Kind `json:"kind"`
 
 	// Name is the name of the referent. When unspecified, this policy
diff --git a/apis/v1beta1/shared_types.go b/apis/v1beta1/shared_types.go
index 3dbcc280..ce1c4306 100644
--- a/apis/v1beta1/shared_types.go
+++ b/apis/v1beta1/shared_types.go
@@ -40,9 +40,6 @@ type ParentReference = v1.ParentReference
 type CommonRouteSpec = v1.CommonRouteSpec
 
 // PortNumber defines a network port.
-//
-// +kubebuilder:validation:Minimum=1
-// +kubebuilder:validation:Maximum=65535
 type PortNumber = v1.PortNumber
 
 // BackendRef defines how a Route should forward a request to a Kubernetes
diff --git a/apisx/v1alpha1/shared_types.go b/apisx/v1alpha1/shared_types.go
index f811ace8..441d4758 100644
--- a/apisx/v1alpha1/shared_types.go
+++ b/apisx/v1alpha1/shared_types.go
@@ -70,6 +70,7 @@ type ParentGatewayReference struct {
 	Kind *Kind `json:"kind"`
 
 	// Name is the name of the referent.
+	// +required
 	Name ObjectName `json:"name"`
 
 	// Namespace is the namespace of the referent.  If not present,
@@ -87,6 +88,7 @@ type RequestRate struct {
 	// Support: Extended
 	// +kubebuilder:validation:Minimum=1
 	// +kubebuilder:validation:Maximum=1000000
+	// +optional
 	Count *int `json:"count,omitempty"`
 
 	// Interval specifies the divisor of the rate of requests, the amount of
@@ -94,5 +96,6 @@ type RequestRate struct {
 	//
 	// Support: Extended
 	// +kubebuilder:validation:XValidation:message="interval can not be greater than one hour",rule="!(duration(self) == duration('0s') || duration(self) > duration('1h'))"
+	// +optional
 	Interval *Duration `json:"interval,omitempty"`
 }
diff --git a/apisx/v1alpha1/xbackendtrafficpolicy_types.go b/apisx/v1alpha1/xbackendtrafficpolicy_types.go
index b2dcba69..3ac51636 100644
--- a/apisx/v1alpha1/xbackendtrafficpolicy_types.go
+++ b/apisx/v1alpha1/xbackendtrafficpolicy_types.go
@@ -37,13 +37,16 @@ type XBackendTrafficPolicy struct {
 	//
 	// +optional
 
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of BackendTrafficPolicy.
+	// +required
 	Spec BackendTrafficPolicySpec `json:"spec"`
 
 	// Status defines the current state of BackendTrafficPolicy.
+	// +optional
 	Status PolicyStatus `json:"status,omitempty"`
 }
 
@@ -72,6 +75,7 @@ type BackendTrafficPolicySpec struct {
 	// +listMapKey=name
 	// +kubebuilder:validation:MinItems=1
 	// +kubebuilder:validation:MaxItems=16
+	// +required
 	TargetRefs []LocalPolicyTargetReference `json:"targetRefs"`
 
 	// RetryConstraint defines the configuration for when to allow or prevent
diff --git a/apisx/v1alpha1/xlistenerset_types.go b/apisx/v1alpha1/xlistenerset_types.go
index 92cca1b7..fd108e2b 100644
--- a/apisx/v1alpha1/xlistenerset_types.go
+++ b/apisx/v1alpha1/xlistenerset_types.go
@@ -57,21 +57,25 @@ import (
 //   - False: when AllowedListeners is set but no valid listeners are attached, or when AllowedListeners is not set or false
 //   - Unknown: when no AllowedListeners config is present
 type XListenerSet struct {
-	metav1.TypeMeta   `json:",inline"`
+	metav1.TypeMeta `json:",inline"`
+	// +optional
 	metav1.ObjectMeta `json:"metadata,omitempty"`
 
 	// Spec defines the desired state of ListenerSet.
+	// +required
 	Spec ListenerSetSpec `json:"spec"`
 
 	// Status defines the current state of ListenerSet.
 	//
 	// +kubebuilder:default={conditions: {{type: "Accepted", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"},{type: "Programmed", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}}
+	// +optional
 	Status ListenerSetStatus `json:"status,omitempty"`
 }
 
 // ListenerSetSpec defines the desired state of a ListenerSet.
 type ListenerSetSpec struct {
 	// ParentRef references the Gateway that the listeners are attached to.
+	// +required
 	ParentRef ParentGatewayReference `json:"parentRef"`
 
 	// Listeners associated with this ListenerSet. Listeners define
@@ -110,6 +114,7 @@ type ListenerSetSpec struct {
 	// +kubebuilder:validation:XValidation:message="hostname must not be specified for protocols ['TCP', 'UDP']",rule="self.all(l, l.protocol in ['TCP', 'UDP']  ? (!has(l.hostname) || l.hostname == '') : true)"
 	// +kubebuilder:validation:XValidation:message="Listener name must be unique within the Gateway",rule="self.all(l1, self.exists_one(l2, l1.name == l2.name))"
 	// +kubebuilder:validation:XValidation:message="Combination of port, protocol and hostname must be unique for each listener",rule="self.all(l1, !has(l1.port) || self.exists_one(l2, has(l2.port) && l1.port == l2.port && l1.protocol == l2.protocol && (has(l1.hostname) && has(l2.hostname) ? l1.hostname == l2.hostname : !has(l1.hostname) && !has(l2.hostname))))"
+	// +required
 	Listeners []ListenerEntry `json:"listeners"`
 }
 
@@ -120,6 +125,7 @@ type ListenerEntry struct {
 	// Name is not required to be unique across a Gateway and ListenerSets.
 	// Routes can attach to a Listener by having a ListenerSet as a parentRef
 	// and setting the SectionName
+	// +required
 	Name SectionName `json:"name"`
 
 	// Hostname specifies the virtual hostname to match for protocol types that
@@ -152,9 +158,21 @@ type ListenerEntry struct {
 
 	// Port is the network port. Multiple listeners may use the
 	// same port, subject to the Listener compatibility rules.
-	Port PortNumber `json:"port"`
+	//
+	// If the port is not set or specified as zero, the implementation will assign
+	// a unique port. If the implementation does not support dynamic port
+	// assignment, it MUST set `Accepted` condition to `False` with the
+	// `UnsupportedPort` reason.
+	//
+	// +optional
+	//
+	// +kubebuilder:default=0
+	// +kubebuilder:validation:Minimum=0
+	// +kubebuilder:validation:Maximum=65535
+	Port PortNumber `json:"port,omitempty"`
 
 	// Protocol specifies the network protocol this listener expects to receive.
+	// +required
 	Protocol ProtocolType `json:"protocol"`
 
 	// TLS is the TLS configuration for the Listener. This field is required if
@@ -230,9 +248,15 @@ type ListenerSetStatus struct {
 // ListenerStatus is the status associated with a Listener.
 type ListenerEntryStatus struct {
 	// Name is the name of the Listener that this status corresponds to.
+	// +required
 	Name SectionName `json:"name"`
 
 	// Port is the network port the listener is configured to listen on.
+	//
+	// +kubebuilder:validation:Minimum=1
+	// +kubebuilder:validation:Maximum=65535
+	//
+	// +required
 	Port PortNumber `json:"port"`
 
 	// SupportedKinds is the list indicating the Kinds supported by this
@@ -245,6 +269,8 @@ type ListenerEntryStatus struct {
 	// and invalid Route kinds are specified, the implementation MUST
 	// reference the valid Route kinds that have been specified.
 	//
+	// +required
+	// +listType=atomic
 	// +kubebuilder:validation:MaxItems=8
 	SupportedKinds []RouteGroupKind `json:"supportedKinds"`
 
@@ -265,6 +291,7 @@ type ListenerEntryStatus struct {
 	//
 	// Uses for this field include troubleshooting Route attachment and
 	// measuring blast radius/impact of changes to a Listener.
+	// +required
 	AttachedRoutes int32 `json:"attachedRoutes"`
 
 	// Conditions describe the current condition of this listener.
@@ -272,6 +299,7 @@ type ListenerEntryStatus struct {
 	// +listType=map
 	// +listMapKey=type
 	// +kubebuilder:validation:MaxItems=8
+	// +required
 	Conditions []metav1.Condition `json:"conditions"`
 }
 
diff --git a/applyconfiguration/internal/internal.go b/applyconfiguration/internal/internal.go
index 0403df0d..92508d3a 100644
--- a/applyconfiguration/internal/internal.go
+++ b/applyconfiguration/internal/internal.go
@@ -1795,7 +1795,6 @@ var schemaYAML = typed.YAMLObject(`types:
     - name: port
       type:
         scalar: numeric
-      default: 0
     - name: protocol
       type:
         scalar: string
diff --git a/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml b/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml
index a2a5506c..8622def6 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_backendtlspolicies.yaml
@@ -149,6 +149,7 @@ spec:
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName must be specified when targetRefs includes
                     2 or more references to the same target
@@ -226,6 +227,7 @@ spec:
                       type: object
                     maxItems: 8
                     type: array
+                    x-kubernetes-list-type: atomic
                   hostname:
                     description: |-
                       Hostname is used for two purposes in the connection between Gateways and
@@ -302,6 +304,7 @@ spec:
                           "")'
                     maxItems: 5
                     type: array
+                    x-kubernetes-list-type: atomic
                   wellKnownCACertificates:
                     description: |-
                       WellKnownCACertificates specifies whether system CA certificates may be used in
@@ -623,10 +626,12 @@ spec:
                       type: string
                   required:
                   - ancestorRef
+                  - conditions
                   - controllerName
                   type: object
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - ancestors
             type: object
diff --git a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
index 328999ee..2e2462a0 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_gateways.yaml
@@ -126,6 +126,7 @@ spec:
                       true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: IPAddress values must be unique
                   rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2,
@@ -633,6 +634,7 @@ spec:
                             type: object
                           maxItems: 8
                           type: array
+                          x-kubernetes-list-type: atomic
                         namespaces:
                           default:
                             from: Same
@@ -887,6 +889,7 @@ spec:
                             type: object
                           maxItems: 64
                           type: array
+                          x-kubernetes-list-type: atomic
                         frontendValidation:
                           description: |-
                             FrontendValidation holds configuration information for validating the frontend (client).
@@ -973,6 +976,9 @@ spec:
                               maxItems: 8
                               minItems: 1
                               type: array
+                              x-kubernetes-list-type: atomic
+                          required:
+                          - caCertificateRefs
                           type: object
                         mode:
                           default: Terminate
@@ -1126,6 +1132,7 @@ spec:
                       true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               conditions:
                 default:
                 - lastTransitionTime: "1970-01-01T00:00:00Z"
@@ -1339,6 +1346,7 @@ spec:
                         type: object
                       maxItems: 8
                       type: array
+                      x-kubernetes-list-type: atomic
                   required:
                   - attachedRoutes
                   - conditions
@@ -1464,6 +1472,7 @@ spec:
                       true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: IPAddress values must be unique
                   rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2,
@@ -1971,6 +1980,7 @@ spec:
                             type: object
                           maxItems: 8
                           type: array
+                          x-kubernetes-list-type: atomic
                         namespaces:
                           default:
                             from: Same
@@ -2225,6 +2235,7 @@ spec:
                             type: object
                           maxItems: 64
                           type: array
+                          x-kubernetes-list-type: atomic
                         frontendValidation:
                           description: |-
                             FrontendValidation holds configuration information for validating the frontend (client).
@@ -2311,6 +2322,9 @@ spec:
                               maxItems: 8
                               minItems: 1
                               type: array
+                              x-kubernetes-list-type: atomic
+                          required:
+                          - caCertificateRefs
                           type: object
                         mode:
                           default: Terminate
@@ -2464,6 +2478,7 @@ spec:
                       true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               conditions:
                 default:
                 - lastTransitionTime: "1970-01-01T00:00:00Z"
@@ -2677,6 +2692,7 @@ spec:
                         type: object
                       maxItems: 8
                       type: array
+                      x-kubernetes-list-type: atomic
                   required:
                   - attachedRoutes
                   - conditions
diff --git a/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml
index 9e8dd642..3a40ee23 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_grpcroutes.yaml
@@ -151,6 +151,7 @@ spec:
                   type: string
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               parentRefs:
                 description: |-
                   ParentRefs references the resources (usually Gateways) that a Route wants
@@ -363,6 +364,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName or port must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -984,6 +986,7 @@ spec:
                                 rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
                             maxItems: 16
                             type: array
+                            x-kubernetes-list-type: atomic
                             x-kubernetes-validations:
                             - message: RequestHeaderModifier filter cannot be repeated
                               rule: self.filter(f, f.type == 'RequestHeaderModifier').size()
@@ -1080,6 +1083,7 @@ spec:
                             ? has(self.port) : true'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                     filters:
                       description: |-
                         Filters define the filters that are applied to requests that match
@@ -1630,6 +1634,7 @@ spec:
                           rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                       x-kubernetes-validations:
                       - message: RequestHeaderModifier filter cannot be repeated
                         rule: self.filter(f, f.type == 'RequestHeaderModifier').size()
@@ -1807,6 +1812,7 @@ spec:
                         type: object
                       maxItems: 64
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -1908,6 +1914,7 @@ spec:
                   type: object
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: While 16 rules and 64 matches per rule are allowed, the
                     total number of matches across all rules in a route must be less
@@ -2196,14 +2203,18 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
+        required:
+        - spec
         type: object
     served: true
     storage: true
diff --git a/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml
index fe5b7f03..65515a4e 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_httproutes.yaml
@@ -131,6 +131,7 @@ spec:
                   type: string
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               parentRefs:
                 description: |-
                   ParentRefs references the resources (usually Gateways) that a Route wants
@@ -343,6 +344,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName or port must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -1523,6 +1525,7 @@ spec:
                                 rule: '!(!has(self.cors) && self.type == ''CORS'')'
                             maxItems: 16
                             type: array
+                            x-kubernetes-list-type: atomic
                             x-kubernetes-validations:
                             - message: May specify either httpRouteFilterRequestRedirect
                                 or httpRouteFilterRequestRewrite, but not both
@@ -1629,6 +1632,7 @@ spec:
                             ? has(self.port) : true'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                     filters:
                       description: |-
                         Filters define the filters that are applied to requests that match
@@ -2736,6 +2740,7 @@ spec:
                           rule: '!(!has(self.cors) && self.type == ''CORS'')'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                       x-kubernetes-validations:
                       - message: May specify either httpRouteFilterRequestRedirect
                           or httpRouteFilterRequestRewrite, but not both
@@ -3047,6 +3052,7 @@ spec:
                         type: object
                       maxItems: 64
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -3142,6 +3148,7 @@ spec:
                             minimum: 400
                             type: integer
                           type: array
+                          x-kubernetes-list-type: atomic
                       type: object
                     sessionPersistence:
                       description: |-
@@ -3337,6 +3344,7 @@ spec:
                       != ''PathPrefix'') ? false : true) : true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: While 16 rules and 64 matches per rule are allowed, the
                     total number of matches across all rules in a route must be less
@@ -3619,11 +3627,13 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
@@ -3747,6 +3757,7 @@ spec:
                   type: string
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               parentRefs:
                 description: |-
                   ParentRefs references the resources (usually Gateways) that a Route wants
@@ -3959,6 +3970,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName or port must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -5139,6 +5151,7 @@ spec:
                                 rule: '!(!has(self.cors) && self.type == ''CORS'')'
                             maxItems: 16
                             type: array
+                            x-kubernetes-list-type: atomic
                             x-kubernetes-validations:
                             - message: May specify either httpRouteFilterRequestRedirect
                                 or httpRouteFilterRequestRewrite, but not both
@@ -5245,6 +5258,7 @@ spec:
                             ? has(self.port) : true'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                     filters:
                       description: |-
                         Filters define the filters that are applied to requests that match
@@ -6352,6 +6366,7 @@ spec:
                           rule: '!(!has(self.cors) && self.type == ''CORS'')'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                       x-kubernetes-validations:
                       - message: May specify either httpRouteFilterRequestRedirect
                           or httpRouteFilterRequestRewrite, but not both
@@ -6663,6 +6678,7 @@ spec:
                         type: object
                       maxItems: 64
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -6758,6 +6774,7 @@ spec:
                             minimum: 400
                             type: integer
                           type: array
+                          x-kubernetes-list-type: atomic
                       type: object
                     sessionPersistence:
                       description: |-
@@ -6953,6 +6970,7 @@ spec:
                       != ''PathPrefix'') ? false : true) : true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: While 16 rules and 64 matches per rule are allowed, the
                     total number of matches across all rules in a route must be less
@@ -7235,11 +7253,13 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
diff --git a/config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml b/config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml
index a4952e39..ac146b27 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_referencegrants.yaml
@@ -124,6 +124,7 @@ spec:
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
               to:
                 description: |-
                   To describes the resources that may be referenced by the resources
@@ -173,6 +174,7 @@ spec:
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - from
             - to
diff --git a/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml
index 7365304e..9de08325 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_tcproutes.yaml
@@ -262,6 +262,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName or port must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -426,6 +427,7 @@ spec:
                       maxItems: 16
                       minItems: 1
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -435,10 +437,13 @@ spec:
                       minLength: 1
                       pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                       type: string
+                  required:
+                  - backendRefs
                   type: object
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: Rule name must be unique within the route
                   rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
@@ -709,11 +714,13 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
diff --git a/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml
index 8843c2f0..dce65f87 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml
@@ -110,6 +110,7 @@ spec:
                   type: string
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               parentRefs:
                 description: |-
                   ParentRefs references the resources (usually Gateways) that a Route wants
@@ -322,6 +323,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName or port must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -489,6 +491,7 @@ spec:
                       maxItems: 16
                       minItems: 1
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -498,10 +501,13 @@ spec:
                       minLength: 1
                       pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                       type: string
+                  required:
+                  - backendRefs
                   type: object
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: Rule name must be unique within the route
                   rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
@@ -772,11 +778,13 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
@@ -880,6 +888,7 @@ spec:
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
               parentRefs:
                 description: |-
                   ParentRefs references the resources (usually Gateways) that a Route wants
@@ -1092,6 +1101,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName or port must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -1116,7 +1126,7 @@ spec:
                     || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port
                     == p2.port))))
               rules:
-                description: Rules are a list of TLS matchers and actions.
+                description: Rules are a list of actions.
                 items:
                   description: TLSRouteRule is the configuration for a given rule.
                   properties:
@@ -1259,6 +1269,7 @@ spec:
                       maxItems: 16
                       minItems: 1
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -1268,10 +1279,13 @@ spec:
                       minLength: 1
                       pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                       type: string
+                  required:
+                  - backendRefs
                   type: object
-                maxItems: 16
+                maxItems: 1
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: Rule name must be unique within the route
                   rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
@@ -1543,11 +1557,13 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
diff --git a/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml b/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml
index 5ef205c1..1f7be3d3 100644
--- a/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml
+++ b/config/crd/experimental/gateway.networking.k8s.io_udproutes.yaml
@@ -262,6 +262,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName or port must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -426,6 +427,7 @@ spec:
                       maxItems: 16
                       minItems: 1
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -435,10 +437,13 @@ spec:
                       minLength: 1
                       pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                       type: string
+                  required:
+                  - backendRefs
                   type: object
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: Rule name must be unique within the route
                   rule: self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name)
@@ -709,11 +714,13 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
diff --git a/config/crd/experimental/gateway.networking.x-k8s.io_xbackendtrafficpolicies.yaml b/config/crd/experimental/gateway.networking.x-k8s.io_xbackendtrafficpolicies.yaml
index a4674dec..3e6d06b2 100644
--- a/config/crd/experimental/gateway.networking.x-k8s.io_xbackendtrafficpolicies.yaml
+++ b/config/crd/experimental/gateway.networking.x-k8s.io_xbackendtrafficpolicies.yaml
@@ -583,10 +583,12 @@ spec:
                       type: string
                   required:
                   - ancestorRef
+                  - conditions
                   - controllerName
                   type: object
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - ancestors
             type: object
diff --git a/config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml b/config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml
index 2454521c..1a266cca 100644
--- a/config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml
+++ b/config/crd/experimental/gateway.networking.x-k8s.io_xlistenersets.yaml
@@ -174,6 +174,7 @@ spec:
                             type: object
                           maxItems: 8
                           type: array
+                          x-kubernetes-list-type: atomic
                         namespaces:
                           default:
                             from: Same
@@ -296,12 +297,18 @@ spec:
                       pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
                       type: string
                     port:
+                      default: 0
                       description: |-
                         Port is the network port. Multiple listeners may use the
                         same port, subject to the Listener compatibility rules.
+
+                        If the port is not set or specified as zero, the implementation will assign
+                        a unique port. If the implementation does not support dynamic port
+                        assignment, it MUST set `Accepted` condition to `False` with the
+                        `UnsupportedPort` reason.
                       format: int32
                       maximum: 65535
-                      minimum: 1
+                      minimum: 0
                       type: integer
                     protocol:
                       description: Protocol specifies the network protocol this listener
@@ -401,6 +408,7 @@ spec:
                             type: object
                           maxItems: 64
                           type: array
+                          x-kubernetes-list-type: atomic
                         frontendValidation:
                           description: |-
                             FrontendValidation holds configuration information for validating the frontend (client).
@@ -487,6 +495,9 @@ spec:
                               maxItems: 8
                               minItems: 1
                               type: array
+                              x-kubernetes-list-type: atomic
+                          required:
+                          - caCertificateRefs
                           type: object
                         mode:
                           default: Terminate
@@ -539,7 +550,6 @@ spec:
                           > 0 || size(self.options) > 0 : true'
                   required:
                   - name
-                  - port
                   - protocol
                   type: object
                 maxItems: 64
@@ -839,6 +849,7 @@ spec:
                         type: object
                       maxItems: 8
                       type: array
+                      x-kubernetes-list-type: atomic
                   required:
                   - attachedRoutes
                   - conditions
diff --git a/config/crd/standard/gateway.networking.k8s.io_gateways.yaml b/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
index 2952481b..bcb64881 100644
--- a/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
+++ b/config/crd/standard/gateway.networking.k8s.io_gateways.yaml
@@ -126,6 +126,7 @@ spec:
                       true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: IPAddress values must be unique
                   rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2,
@@ -488,6 +489,7 @@ spec:
                             type: object
                           maxItems: 8
                           type: array
+                          x-kubernetes-list-type: atomic
                         namespaces:
                           default:
                             from: Same
@@ -742,6 +744,7 @@ spec:
                             type: object
                           maxItems: 64
                           type: array
+                          x-kubernetes-list-type: atomic
                         mode:
                           default: Terminate
                           description: |-
@@ -894,6 +897,7 @@ spec:
                       true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               conditions:
                 default:
                 - lastTransitionTime: "1970-01-01T00:00:00Z"
@@ -1107,6 +1111,7 @@ spec:
                         type: object
                       maxItems: 8
                       type: array
+                      x-kubernetes-list-type: atomic
                   required:
                   - attachedRoutes
                   - conditions
@@ -1232,6 +1237,7 @@ spec:
                       true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: IPAddress values must be unique
                   rule: 'self.all(a1, a1.type == ''IPAddress'' ? self.exists_one(a2,
@@ -1594,6 +1600,7 @@ spec:
                             type: object
                           maxItems: 8
                           type: array
+                          x-kubernetes-list-type: atomic
                         namespaces:
                           default:
                             from: Same
@@ -1848,6 +1855,7 @@ spec:
                             type: object
                           maxItems: 64
                           type: array
+                          x-kubernetes-list-type: atomic
                         mode:
                           default: Terminate
                           description: |-
@@ -2000,6 +2008,7 @@ spec:
                       true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               conditions:
                 default:
                 - lastTransitionTime: "1970-01-01T00:00:00Z"
@@ -2213,6 +2222,7 @@ spec:
                         type: object
                       maxItems: 8
                       type: array
+                      x-kubernetes-list-type: atomic
                   required:
                   - attachedRoutes
                   - conditions
diff --git a/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml b/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml
index 4f7d8f13..4e81b088 100644
--- a/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml
+++ b/config/crd/standard/gateway.networking.k8s.io_grpcroutes.yaml
@@ -151,6 +151,7 @@ spec:
                   type: string
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               parentRefs:
                 description: |-
                   ParentRefs references the resources (usually Gateways) that a Route wants
@@ -334,6 +335,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -937,6 +939,7 @@ spec:
                                 rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
                             maxItems: 16
                             type: array
+                            x-kubernetes-list-type: atomic
                             x-kubernetes-validations:
                             - message: RequestHeaderModifier filter cannot be repeated
                               rule: self.filter(f, f.type == 'RequestHeaderModifier').size()
@@ -1033,6 +1036,7 @@ spec:
                             ? has(self.port) : true'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                     filters:
                       description: |-
                         Filters define the filters that are applied to requests that match
@@ -1583,6 +1587,7 @@ spec:
                           rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                       x-kubernetes-validations:
                       - message: RequestHeaderModifier filter cannot be repeated
                         rule: self.filter(f, f.type == 'RequestHeaderModifier').size()
@@ -1760,6 +1765,7 @@ spec:
                         type: object
                       maxItems: 64
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -1772,6 +1778,7 @@ spec:
                   type: object
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: While 16 rules and 64 matches per rule are allowed, the
                     total number of matches across all rules in a route must be less
@@ -2039,14 +2046,18 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
+        required:
+        - spec
         type: object
     served: true
     storage: true
diff --git a/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml b/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
index 1824bd5e..dfa6af4c 100644
--- a/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
+++ b/config/crd/standard/gateway.networking.k8s.io_httproutes.yaml
@@ -131,6 +131,7 @@ spec:
                   type: string
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               parentRefs:
                 description: |-
                   ParentRefs references the resources (usually Gateways) that a Route wants
@@ -314,6 +315,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -1190,6 +1192,7 @@ spec:
                                 rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
                             maxItems: 16
                             type: array
+                            x-kubernetes-list-type: atomic
                             x-kubernetes-validations:
                             - message: May specify either httpRouteFilterRequestRedirect
                                 or httpRouteFilterRequestRewrite, but not both
@@ -1296,6 +1299,7 @@ spec:
                             ? has(self.port) : true'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                     filters:
                       description: |-
                         Filters define the filters that are applied to requests that match
@@ -2117,6 +2121,7 @@ spec:
                           rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                       x-kubernetes-validations:
                       - message: May specify either httpRouteFilterRequestRedirect
                           or httpRouteFilterRequestRewrite, but not both
@@ -2428,6 +2433,7 @@ spec:
                         type: object
                       maxItems: 64
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -2542,6 +2548,7 @@ spec:
                       != ''PathPrefix'') ? false : true) : true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: While 16 rules and 64 matches per rule are allowed, the
                     total number of matches across all rules in a route must be less
@@ -2803,11 +2810,13 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
@@ -2931,6 +2940,7 @@ spec:
                   type: string
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
               parentRefs:
                 description: |-
                   ParentRefs references the resources (usually Gateways) that a Route wants
@@ -3114,6 +3124,7 @@ spec:
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: sectionName must be specified when parentRefs includes
                     2 or more references to the same parent
@@ -3990,6 +4001,7 @@ spec:
                                 rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
                             maxItems: 16
                             type: array
+                            x-kubernetes-list-type: atomic
                             x-kubernetes-validations:
                             - message: May specify either httpRouteFilterRequestRedirect
                                 or httpRouteFilterRequestRewrite, but not both
@@ -4096,6 +4108,7 @@ spec:
                             ? has(self.port) : true'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                     filters:
                       description: |-
                         Filters define the filters that are applied to requests that match
@@ -4917,6 +4930,7 @@ spec:
                           rule: '!(!has(self.extensionRef) && self.type == ''ExtensionRef'')'
                       maxItems: 16
                       type: array
+                      x-kubernetes-list-type: atomic
                       x-kubernetes-validations:
                       - message: May specify either httpRouteFilterRequestRedirect
                           or httpRouteFilterRequestRewrite, but not both
@@ -5228,6 +5242,7 @@ spec:
                         type: object
                       maxItems: 64
                       type: array
+                      x-kubernetes-list-type: atomic
                     name:
                       description: |-
                         Name is the name of the route rule. This name MUST be unique within a Route if it is set.
@@ -5342,6 +5357,7 @@ spec:
                       != ''PathPrefix'') ? false : true) : true'
                 maxItems: 16
                 type: array
+                x-kubernetes-list-type: atomic
                 x-kubernetes-validations:
                 - message: While 16 rules and 64 matches per rule are allowed, the
                     total number of matches across all rules in a route must be less
@@ -5603,11 +5619,13 @@ spec:
                       - name
                       type: object
                   required:
+                  - conditions
                   - controllerName
                   - parentRef
                   type: object
                 maxItems: 32
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - parents
             type: object
diff --git a/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml b/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml
index da71ceaa..6a2d3689 100644
--- a/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml
+++ b/config/crd/standard/gateway.networking.k8s.io_referencegrants.yaml
@@ -124,6 +124,7 @@ spec:
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
               to:
                 description: |-
                   To describes the resources that may be referenced by the resources
@@ -173,6 +174,7 @@ spec:
                 maxItems: 16
                 minItems: 1
                 type: array
+                x-kubernetes-list-type: atomic
             required:
             - from
             - to
diff --git a/conformance/reports/v1.2.1/azure-application-gateway-for-containers/README.md b/conformance/reports/v1.2.1/azure-application-gateway-for-containers/README.md
new file mode 100644
index 00000000..22b7f949
--- /dev/null
+++ b/conformance/reports/v1.2.1/azure-application-gateway-for-containers/README.md
@@ -0,0 +1,13 @@
+# Azure Application Gateway for Containers
+
+[Application Gateway for Containers][azure-application-gateway-for-containers] is a managed application (layer 7) load balancing solution, providing dynamic traffic management capabilities for workloads running in a Kubernetes cluster in Azure. Follow the [quickstart guide][azure-application-gateway-for-containers-quickstart-controller] to deploy the ALB controller and get started with Gateway API.
+
+## Table of Contents
+
+|API channel|Implementation version|Mode|Report|
+|-----------|----------------------|----|------|
+|standard|[v1.2.1](https://learn.microsoft.com/azure/application-gateway/for-containers/alb-controller-release-notes#latest-release-recommended)|default|[v1.2.1 report](./standard-v1.2.1-default-report.yaml)|
+
+
+[azure-application-gateway-for-containers]:https://aka.ms/appgwcontainers/docs
+[azure-application-gateway-for-containers-quickstart-controller]:https://aka.ms/appgwcontainers/docs
diff --git a/conformance/reports/v1.2.1/azure-application-gateway-for-containers/standard-v1.2.1-default-report.yaml b/conformance/reports/v1.2.1/azure-application-gateway-for-containers/standard-v1.2.1-default-report.yaml
new file mode 100644
index 00000000..b15b81ef
--- /dev/null
+++ b/conformance/reports/v1.2.1/azure-application-gateway-for-containers/standard-v1.2.1-default-report.yaml
@@ -0,0 +1,59 @@
+apiVersion: gateway.networking.k8s.io/v1
+date: "2025-07-18T23:02:29Z"
+gatewayAPIChannel: standard
+gatewayAPIVersion: v1.2.1
+implementation:
+  organization: Microsoft Azure
+  project: Application Gateway for Containers
+  url: https://aka.ms/appgwcontainers/docs
+  version: "1.7.9"
+  contact:
+  - agcfeedback@microsoft.com
+kind: ConformanceReport
+mode: default
+profiles:
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 12
+      Skipped: 0
+  name: GATEWAY-GRPC
+  summary: Core tests succeeded.
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 33
+      Skipped: 0
+  extended:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 9
+      Skipped: 0
+    supportedFeatures:
+    - HTTPRouteDestinationPortMatching
+    - HTTPRouteHostRewrite
+    - HTTPRouteMethodMatching
+    - HTTPRoutePathRedirect
+    - HTTPRoutePathRewrite
+    - HTTPRoutePortRedirect
+    - HTTPRouteQueryParamMatching
+    - HTTPRouteResponseHeaderModification
+    - HTTPRouteSchemeRedirect
+    unsupportedFeatures:
+    - GatewayHTTPListenerIsolation
+    - GatewayInfrastructurePropagation
+    - GatewayPort8080
+    - GatewayStaticAddresses
+    - HTTPRouteBackendProtocolH2C
+    - HTTPRouteBackendProtocolWebSocket
+    - HTTPRouteBackendRequestHeaderModification
+    - HTTPRouteBackendTimeout
+    - HTTPRouteParentRefPort
+    - HTTPRouteRequestMirror
+    - HTTPRouteRequestMultipleMirrors
+    - HTTPRouteRequestTimeout
+  name: GATEWAY-HTTP
+  summary: Core tests succeeded. Extended tests succeeded.
diff --git a/conformance/reports/v1.2.1/nginx-nginx-gateway-fabric/README.md b/conformance/reports/v1.2.1/nginx-nginx-gateway-fabric/README.md
index 75cbb4c1..ab4c8300 100644
--- a/conformance/reports/v1.2.1/nginx-nginx-gateway-fabric/README.md
+++ b/conformance/reports/v1.2.1/nginx-nginx-gateway-fabric/README.md
@@ -5,6 +5,7 @@
 | API channel  | Implementation version                                                      | Mode    | Report                                           |
 |--------------|-----------------------------------------------------------------------------|---------|--------------------------------------------------|
 | experimental | [v1.6.0](https://github.com/nginx/nginx-gateway-fabric/releases/tag/v1.6.0) | default | [v1.6.0 report](./experimental-1.6.0-default-report.yaml) |
+| experimental | [v2.0.2](https://github.com/nginx/nginx-gateway-fabric/releases/tag/v2.0.2) | default | [v2.0.2 report](./experimental-2.0.2-default-report.yaml) |
 
 ## Reproduce
 
diff --git a/conformance/reports/v1.2.1/nginx-nginx-gateway-fabric/experimental-2.0.2-default-report.yaml b/conformance/reports/v1.2.1/nginx-nginx-gateway-fabric/experimental-2.0.2-default-report.yaml
new file mode 100644
index 00000000..6f42f47e
--- /dev/null
+++ b/conformance/reports/v1.2.1/nginx-nginx-gateway-fabric/experimental-2.0.2-default-report.yaml
@@ -0,0 +1,93 @@
+apiVersion: gateway.networking.k8s.io/v1
+date: "2025-07-25T15:36:44Z"
+gatewayAPIChannel: experimental
+gatewayAPIVersion: v1.2.1
+implementation:
+  contact:
+  - https://github.com/nginx/nginx-gateway-fabric/discussions/new/choose
+  organization: nginx
+  project: nginx-gateway-fabric
+  url: https://github.com/nginx/nginx-gateway-fabric
+  version: v2.0.2
+kind: ConformanceReport
+mode: default
+profiles:
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 33
+      Skipped: 0
+  extended:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 14
+      Skipped: 0
+    supportedFeatures:
+    - GatewayHTTPListenerIsolation
+    - GatewayInfrastructurePropagation
+    - GatewayPort8080
+    - HTTPRouteHostRewrite
+    - HTTPRouteMethodMatching
+    - HTTPRoutePathRedirect
+    - HTTPRoutePathRewrite
+    - HTTPRoutePortRedirect
+    - HTTPRouteQueryParamMatching
+    - HTTPRouteRequestMirror
+    - HTTPRouteRequestMultipleMirrors
+    - HTTPRouteResponseHeaderModification
+    - HTTPRouteSchemeRedirect
+    unsupportedFeatures:
+    - GatewayStaticAddresses
+    - HTTPRouteBackendProtocolH2C
+    - HTTPRouteBackendProtocolWebSocket
+    - HTTPRouteBackendRequestHeaderModification
+    - HTTPRouteBackendTimeout
+    - HTTPRouteDestinationPortMatching
+    - HTTPRouteParentRefPort
+    - HTTPRouteRequestTimeout
+  name: GATEWAY-HTTP
+  summary: Core tests succeeded. Extended tests succeeded.
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 11
+      Skipped: 0
+  extended:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 1
+      Skipped: 0
+    supportedFeatures:
+    - GatewayHTTPListenerIsolation
+    - GatewayInfrastructurePropagation
+    - GatewayPort8080
+    unsupportedFeatures:
+    - GatewayStaticAddresses
+  name: GATEWAY-TLS
+  summary: Core tests succeeded. Extended tests succeeded.
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 12
+      Skipped: 0
+  extended:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 1
+      Skipped: 0
+    supportedFeatures:
+    - GatewayHTTPListenerIsolation
+    - GatewayInfrastructurePropagation
+    - GatewayPort8080
+    unsupportedFeatures:
+    - GatewayStaticAddresses
+  name: GATEWAY-GRPC
+  summary: Core tests succeeded. Extended tests succeeded.
+succeededProvisionalTests:
+- GatewayInfrastructure
diff --git a/conformance/utils/http/http.go b/conformance/utils/http/http.go
index e1aca27d..da7036da 100644
--- a/conformance/utils/http/http.go
+++ b/conformance/utils/http/http.go
@@ -17,7 +17,9 @@ limitations under the License.
 package http
 
 import (
+	"crypto/rand"
 	"fmt"
+	"math/big"
 	"net"
 	"net/url"
 	"strings"
@@ -117,6 +119,17 @@ func MakeRequestAndExpectEventuallyConsistentResponse(t *testing.T, r roundtripp
 	WaitForConsistentResponse(t, r, req, expected, timeoutConfig.RequiredConsecutiveSuccesses, timeoutConfig.MaxTimeToConsistency)
 }
 
+// MakeRequestAndExpectFailure makes a request with the given parameters.
+// This function needs to ensure that after the system is stable the Request is
+// not returning http 200 StatusCode.
+func MakeRequestAndExpectFailure(t *testing.T, r roundtripper.RoundTripper, timeoutConfig config.TimeoutConfig, gwAddr string, expected ExpectedResponse) {
+	t.Helper()
+
+	req := MakeRequest(t, &expected, gwAddr, "HTTP", "http")
+
+	WaitForConsistentFailureResponse(t, r, req, 5, timeoutConfig.MaxTimeToConsistency)
+}
+
 func MakeRequest(t *testing.T, expected *ExpectedResponse, gwAddr, protocol, scheme string) roundtripper.Request {
 	t.Helper()
 
@@ -261,6 +274,29 @@ func WaitForConsistentResponse(t *testing.T, r roundtripper.RoundTripper, req ro
 	tlog.Logf(t, "Request passed")
 }
 
+// WaitForConsistentFailureResponse repeats the provided request for the given
+// period of time and ensures an error is returned each time. This function fails
+// when HTTP Status OK (200) is returned.
+func WaitForConsistentFailureResponse(t *testing.T, r roundtripper.RoundTripper, req roundtripper.Request, threshold int, maxTimeToConsistency time.Duration) {
+	AwaitConvergence(t, threshold, maxTimeToConsistency, func(elapsed time.Duration) bool {
+		_, cRes, err := r.CaptureRoundTrip(req)
+		if err != nil {
+			tlog.Logf(t, "Request failed, not ready yet: %v (after %v)", err.Error(), elapsed)
+			return false
+		}
+		if roundtripper.IsTimeoutError(cRes.StatusCode) {
+			tlog.Logf(t, "Response expectation failed for request: %+v  not ready yet: %v (after %v)", req, cRes.StatusCode, elapsed)
+			return false
+		}
+		if cRes.StatusCode == 200 { // http:StatusCode OK
+			t.Fatalf("Request %+v should failed, returned HTTP Status OK (200) instead", req)
+			return false
+		}
+		return true
+	})
+	tlog.Logf(t, "Expectation for failing Request are met")
+}
+
 func CompareRoundTrip(t *testing.T, req *roundtripper.Request, cReq *roundtripper.CapturedRequest, cRes *roundtripper.CapturedResponse, expected ExpectedResponse) error {
 	if roundtripper.IsTimeoutError(cRes.StatusCode) {
 		if roundtripper.IsTimeoutError(expected.Response.StatusCode) {
@@ -444,3 +480,54 @@ func setRedirectRequestDefaults(req *roundtripper.Request, cRes *roundtripper.Ca
 		expected.RedirectRequest.Path = req.URL.Path
 	}
 }
+
+// addEntropy adds jitter to the request by adding either a delay up to 1 second, or a random header value, or both.
+func AddEntropy(exp *ExpectedResponse) error {
+	randomNumber := func(limit int64) (*int64, error) {
+		number, err := rand.Int(rand.Reader, big.NewInt(limit))
+		if err != nil {
+			return nil, err
+		}
+		n := number.Int64()
+		return &n, nil
+	}
+
+	// adds a delay
+	delay := func(limit int64) error {
+		randomSleepDuration, err := randomNumber(limit)
+		if err != nil {
+			return err
+		}
+		time.Sleep(time.Duration(*randomSleepDuration) * time.Millisecond)
+		return nil
+	}
+	// adds random header value
+	randomHeader := func(limit int64) error {
+		randomHeaderValue, err := randomNumber(limit)
+		if err != nil {
+			return err
+		}
+		exp.Request.Headers = make(map[string]string)
+		exp.Request.Headers["X-Jitter"] = fmt.Sprintf("%d", *randomHeaderValue)
+		return nil
+	}
+
+	random, err := randomNumber(3)
+	if err != nil {
+		return err
+	}
+
+	switch *random {
+	case 0:
+		return delay(1000)
+	case 1:
+		return randomHeader(10000)
+	case 2:
+		if err := delay(1000); err != nil {
+			return err
+		}
+		return randomHeader(10000)
+	default:
+		return fmt.Errorf("invalid random value: %d", *random)
+	}
+}
diff --git a/conformance/utils/kubernetes/helpers.go b/conformance/utils/kubernetes/helpers.go
index 9e385b4c..8075132d 100644
--- a/conformance/utils/kubernetes/helpers.go
+++ b/conformance/utils/kubernetes/helpers.go
@@ -37,6 +37,7 @@ import (
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
 	"sigs.k8s.io/gateway-api/apis/v1alpha2"
+	"sigs.k8s.io/gateway-api/apis/v1alpha3"
 	"sigs.k8s.io/gateway-api/conformance/utils/config"
 	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
 )
@@ -993,3 +994,35 @@ func findPodConditionInList(t *testing.T, conditions []v1.PodCondition, condName
 	tlog.Logf(t, "%s was not in conditions list", condName)
 	return false
 }
+
+// BackendTLSPolicyMustHaveCondition checks that the created BackentTLSPolicy has the Condition,
+// halting after the specified timeout is exceeded.
+func BackendTLSPolicyMustHaveCondition(t *testing.T, client client.Client, timeoutConfig config.TimeoutConfig, policyNN, gwNN types.NamespacedName, condition metav1.Condition) {
+	t.Helper()
+	waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, timeoutConfig.HTTPRouteMustHaveCondition, true, func(ctx context.Context) (bool, error) {
+		policy := &v1alpha3.BackendTLSPolicy{}
+		err := client.Get(ctx, policyNN, policy)
+		if err != nil {
+			return false, fmt.Errorf("error fetching BackendTLSPolicy: %w", err)
+		}
+
+		for _, parent := range policy.Status.Ancestors {
+			if err := ConditionsHaveLatestObservedGeneration(policy, parent.Conditions); err != nil {
+				tlog.Logf(t, "BackendTLSPolicy %s (parentRef=%v) %v",
+					policyNN, parentRefToString(parent.AncestorRef), err,
+				)
+				return false, nil
+			}
+
+			if parent.AncestorRef.Name == gatewayv1.ObjectName(gwNN.Name) && (parent.AncestorRef.Namespace == nil || string(*parent.AncestorRef.Namespace) == gwNN.Namespace) {
+				if findConditionInList(t, parent.Conditions, condition.Type, string(condition.Status), condition.Reason) {
+					return true, nil
+				}
+			}
+		}
+
+		return false, nil
+	})
+
+	require.NoErrorf(t, waitErr, "error waiting for BackendTLSPolicy status to have a Condition %v", condition)
+}
diff --git a/conformance/utils/suite/suite.go b/conformance/utils/suite/suite.go
index 63a6b93a..23c93653 100644
--- a/conformance/utils/suite/suite.go
+++ b/conformance/utils/suite/suite.go
@@ -211,8 +211,13 @@ func NewConformanceTestSuite(options ConformanceOptions) (*ConformanceTestSuite,
 			return nil, fmt.Errorf("cannot infer supported features: %w", err)
 		}
 
-		if hasMeshFeatures(supportedFeatures) {
-			return nil, fmt.Errorf("mesh features should not be populated in GatewayClass")
+		// If Mesh features are populated in the GatewayClass we remove them from the supported features set.
+		meshFeatureNames := features.SetsToNamesSet(features.MeshCoreFeatures, features.MeshExtendedFeatures)
+		for _, f := range supportedFeatures.UnsortedList() {
+			if meshFeatureNames.Has(f) {
+				supportedFeatures.Delete(f)
+				fmt.Printf("WARNING: Mesh feature %q should not be populated in GatewayClass, skipping...", f)
+			}
 		}
 		source = supportedFeaturesSourceInferred
 	}
@@ -383,6 +388,8 @@ func (suite *ConformanceTestSuite) Setup(t *testing.T, tests []ConformanceTest)
 		suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{secret}, suite.Cleanup)
 		secret = kubernetes.MustCreateSelfSignedCertSecret(t, "gateway-conformance-app-backend", "tls-passthrough-checks-certificate", []string{"abc.example.com"})
 		suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{secret}, suite.Cleanup)
+		caConfigMapBST, _, _ := kubernetes.MustCreateCACertConfigMap(t, "gateway-conformance-infra", "backend-tls-mismatch-certificate", []string{"nex.example.com"})
+		suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{caConfigMapBST}, suite.Cleanup)
 		caConfigMap, ca, caPrivKey := kubernetes.MustCreateCACertConfigMap(t, "gateway-conformance-infra", "backend-tls-checks-certificate", []string{"abc.example.com"})
 		suite.Applier.MustApplyObjectsWithCleanup(t, suite.Client, suite.TimeoutConfig, []client.Object{caConfigMap}, suite.Cleanup)
 		secret = kubernetes.MustCreateCASignedCertSecret(t, "gateway-conformance-infra", "tls-checks-certificate", []string{"abc.example.com"}, ca, caPrivKey)
@@ -461,6 +468,9 @@ func (suite *ConformanceTestSuite) Run(t *testing.T, tests []ConformanceTest) er
 	sleepForTestIsolation := false
 	for _, test := range tests {
 		res := testSucceeded
+		if suite.RunTest != "" && test.ShortName != suite.RunTest {
+			res = testSkipped
+		}
 		if suite.SkipTests.Has(test.ShortName) {
 			res = testSkipped
 		}
@@ -655,7 +665,3 @@ func getAPIVersionAndChannel(crds []apiextensionsv1.CustomResourceDefinition) (v
 
 	return version, channel, nil
 }
-
-func hasMeshFeatures(f FeaturesSet) bool {
-	return f.HasAny(features.SetsToNamesSet(features.MeshCoreFeatures, features.MeshExtendedFeatures).UnsortedList()...)
-}
diff --git a/geps/gep-1713/index.md b/geps/gep-1713/index.md
index 4cad39fd..c720b357 100644
--- a/geps/gep-1713/index.md
+++ b/geps/gep-1713/index.md
@@ -163,8 +163,19 @@ type ListenerEntry struct {
 
 	// Port is the network port. Multiple listeners may use the
 	// same port, subject to the Listener compatibility rules.
-	//
+    //
+	// If the port is not set or specified as zero, the implementation will assign
+	// a unique port. If the implementation does not support dynamic port
+	// assignment, it MUST set `Accepted` condition to `False` with the
+	// `UnsupportedPort` reason.
+    //
 	// Support: Core
+	//
+	// +optional
+	//
+	// +kubebuilder:default=0
+	// +kubebuilder:validation:Minimum=0
+	// +kubebuilder:validation:Maximum=65535
 	Port PortNumber `json:"port,omitempty"`
 
 	// Protocol specifies the network protocol this listener expects to receive.
@@ -380,6 +391,10 @@ spec:
 
 `ListenerEntry` is currently a copy of the `Listener` struct with some changes noted in the below sections
 
+#### Port
+
+`Port` is now optional to allow for dynamic port assignment.  If the port is unspecified or set to zero, the implementation will assign a unique port. If the implementation does not support dynamic port assignment, it MUST set `Accepted` condition to `False` with the `UnsupportedPort` reason.
+
 ## Semantics
 
 ### Gateway Changes
diff --git a/geps/gep-1762/index.md b/geps/gep-1762/index.md
index e5f4ebf3..eb25e538 100644
--- a/geps/gep-1762/index.md
+++ b/geps/gep-1762/index.md
@@ -59,6 +59,7 @@ With this configuration, an implementation:
 
 * MUST mark the Gateway as `Programmed` and provide an address in `Status.Addresses` where the Gateway can be reached on each configured port.
 * MUST label all generated resources (Service, Deployment, etc) with `gateway.networking.k8s.io/gateway-name: my-gateway` (where `my-gateway` is the name of the Gateway resource).
+* SHOULD label all generated resources (Service, Deployment, etc) with `gateway.networking.k8s.io/gateway-class-name: my-gateway-class` (where `my-gateway-class` is the name of the GatewayClass resource).
 * MUST provision generated resources in the same namespace as the Gateway if they are namespace scoped resources.
   * Cluster scoped resources are not recommended.
 * SHOULD name all generated resources `my-gateway-example` (`<NAME>-<GATEWAY CLASS>`).
diff --git a/geps/gep-1767/index.md b/geps/gep-1767/index.md
index c115dbf1..14315e19 100644
--- a/geps/gep-1767/index.md
+++ b/geps/gep-1767/index.md
@@ -516,7 +516,7 @@ spec:
         value: /resource/foo
     filters:
     - cors:
-      - allowOrigins:
+        allowOrigins:
         - *
         allowMethods: 
         - GET
@@ -575,7 +575,7 @@ spec:
         value: /resource/foo
     filters:
     - cors:
-      - allowOrigins:
+        allowOrigins:
         - https://foo.example
         - http://foo.example
         allowCredentials: true
diff --git a/geps/gep-1897/index.md b/geps/gep-1897/index.md
index 4571c703..8e24b8bf 100644
--- a/geps/gep-1897/index.md
+++ b/geps/gep-1897/index.md
@@ -214,6 +214,13 @@ configuration. CACertificateRefs is an implementation-specific slice of
 named object references, each containing a single cert. We originally proposed to follow the convention established by the
 [CertificateRefs field on Gateway](https://github.com/kubernetes-sigs/gateway-api/blob/18e79909f7310aafc625ba7c862dfcc67b385250/apis/v1beta1/gateway_types.go#L340)
 , but the CertificateRef requires both a tls.key and tls.crt and a certificate reference only requires the tls.crt.
+If any of the CACertificateRefs cannot be resolved (e.g., the referenced resource does not exist) or is misconfigured (e.g., ConfigMap does not contain a key named `ca.crt`), the `ResolvedRefs` status condition MUST be set to `False` with `Reason: InvalidCACertificateRef`. Connections using that CACertificateRef MUST fail, and the client MUST receive an HTTP 5xx error response.
+References to objects with an unsupported Group and Kind are not valid, and MUST be rejected by the implementation with the `ResolvedRefs` status condition set to `False` and `Reason: UnsupportedFeature`.
+Implementations MAY perform further validation of the certificate content (i.e., checking expiry or enforcing specific formats). If they do, they MUST ensure that the `ResolvedRefs` Condition is `False` and use an implementation-specific `Reason`, like `ExpiredCertificate` or similar.
+If `ResolvedRefs` Condition is `False` implementations SHOULD include a message specifying which references are invalid and explaining why.
+
+If all CertificateRefs cannot be resolved, the BackendTLSPolicy is considered invalid and the implementation MUST set the `Accepted` Condition to `False`, with a reason of `NoCACertificates` and a message explaining this.
+
 WellKnownCACertificates is an optional enum that allows users to specify whether to use the set of CA certificates trusted by the
 Gateway (WellKnownCACertificates specified as "System"), or to use the existing CACertificateRefs (WellKnownCACertificates
 specified as "").  The use and definition of system certificates is implementation-dependent, and the intent is that
@@ -222,8 +229,12 @@ references to Kubernetes objects that contain PEM-encoded TLS certificates, whic
 between the gateway and backend pod. References to a resource in a different namespace are invalid.
 If ClientCertificateRefs is unspecified, then WellKnownCACertificates must be set to "System" for a valid configuration.
 If WellKnownCACertificates is unspecified, then CACertificateRefs must be specified with at least one entry for a valid configuration.
-If WellKnownCACertificates is set to "System" and there are no system trusted certificates or the implementation doesn't define system
-trusted certificates, then the associated TLS connection must fail.
+If an implementation does not support the WellKnownCACertificates, or the provided value is unsupported,the BackendTLSPolicy is considered invalid, and the implementation MUST set the `Accepted` Condition to `False`, with a reason of `UnsupportedFeature` and a message explaining this.
+
+For an invalid BackendTLSPolicy, implementations MUST NOT fall back to unencrypted (plaintext) connections. 
+Instead, the corresponding TLS connection MUST fail, and the client MUST receive an HTTP 5xx error response.
+
+Implementations MUST NOT modify any status other than their own. Ownership of a status is determined by the `controllerName`, which identifies the responsible controller.
 
 The `Hostname` field is required and is to be used to configure the SNI the Gateway should use to connect to the backend.
 Implementations must validate that at least one name in the certificate served by the backend matches this field.
diff --git a/geps/gep-3792/index.md b/geps/gep-3792/index.md
index 802d729c..24410744 100644
--- a/geps/gep-3792/index.md
+++ b/geps/gep-3792/index.md
@@ -42,10 +42,10 @@ In this GEP:
    wrangling the mTLS meshes! Supporting non-mTLS meshes will be a separate
    GEP.
 
-   **Note:** It's important to separate mTLS and HTTPS here. Saying that the
-   mTLS meshes use mTLS for secure communication does not preclude them from
-   using custom protocols on top of mTLS, and certainly does not mean that
-   they must use only HTTPS.
+    **Note:** It's important to separate mTLS and HTTPS here. Saying that the
+    mTLS meshes use mTLS for secure communication does not preclude them from
+    using custom protocols on top of mTLS, and certainly does not mean that
+    they must use only HTTPS.
 
 3. _Authentication_ is the act of verifying the identity of some _principal_;
    what the principal actually is depends on context. For this GEP we will
@@ -56,21 +56,21 @@ In this GEP:
    can't trust what the OCG says about the user unless the OCG successfully
    authenticates itself as a workload.
 
-   **Note:** A single workload will have only one identity, but in practice we
-   often see a single identity being used for multiple workloads (both because
-   multiple replicas of a single workload need to share the same identity, and
-   because some low-security workloads may be grouped together under a single
-   identity).
+    **Note:** A single workload will have only one identity, but in practice we
+    often see a single identity being used for multiple workloads (both because
+    multiple replicas of a single workload need to share the same identity, and
+    because some low-security workloads may be grouped together under a single
+    identity).
 
 4. Finally, we'll distinguish between _inbound_ and _outbound_ behaviors.
 
-   Inbound behaviors are those that are applied to a request _arriving_ at a
-   given workload. Authorization and rate limiting are canonical examples
-   of inbound behaviors.
+    Inbound behaviors are those that are applied to a request _arriving_ at a
+    given workload. Authorization and rate limiting are canonical examples
+    of inbound behaviors.
 
-   Outbound behaviors are those that are applied to a request _leaving_ a
-   given workload. Load balancing, retries, and circuit breakers are canonical
-   examples of outbound behaviors.
+    Outbound behaviors are those that are applied to a request _leaving_ a
+    given workload. Load balancing, retries, and circuit breakers are canonical
+    examples of outbound behaviors.
 
 ## Goals
 
@@ -197,7 +197,7 @@ is sent. (For example, Linkerd requires the originating proxy to send
 transport metadata right after the TLS handshake, and it will reject a
 connection which doesn't do that correctly.)
 
-#### 4. The Discovery Problem
+#### 3. The Discovery Problem
 
 When using a mesh, not every workload in the cluster is required to be meshed
 (for example, it's fairly common to have some namespaces meshed and other
diff --git a/geps/gep-3793/index.md b/geps/gep-3793/index.md
index 9f15ead8..f0cad9a7 100644
--- a/geps/gep-3793/index.md
+++ b/geps/gep-3793/index.md
@@ -1,10 +1,17 @@
 # GEP-3793: Default Gateways
 
 * Issue: [#3793](https://github.com/kubernetes-sigs/gateway-api/issues/3793)
-* Status: Provisional
+* Status: Implementable
 
 (See [status definitions](../overview.md#gep-states).)
 
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
+"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in BCP 14 ([RFC8174]) when, and
+only when, they appear in all capitals, as shown here.
+
+[RFC8174]: https://www.rfc-editor.org/rfc/rfc8174
+
 ## User Story
 
 **[Ana] wants a concept of a default Gateway.**
@@ -17,44 +24,73 @@ just wants to create a Route that "works from the outside world" and she
 really doesn't care what the Gateway is called.
 
 Therefore, Ana would like a way to be able to rely on a default Gateway that
-she doesn't have to explicitly name, and can simply trust to exist.
+she doesn't have to explicitly name, and can simply trust to exist. Ana
+recognizes that this will involve **giving up** a certain amount of control
+over how requests reach her workloads. She's OK with that, and she understands
+that it means that relying on a default Gateway is not always appropriate: for
+example, if she needs to be sure that her Route is protected by specific
+authorization policies, she should confer with Chihiro to make sure that she
+explicitly specifies a Gateway that meets those requirements.
 
-[Ana]: https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ana
+In the future, it may also be important to distinguish different kinds of
+default Gateways -- for example, a default ingress Gateway or a default egress
+Gateway. This GEP deliberately defines only a single _scope_ of default
+Gateway (`All`) but recognizes the need to at least consider the possibility
+of multiple scopes in the future.
+
+## Definitions
+
+- **defaulted Route**: a Route that Ana creates without explicitly specifying
+  a Gateway
+
+- **default Gateway**: a Gateway that Chihiro has configured to accept
+  defaulted Routes
+
+- **default Gateway scope**: the scope within which a default Gateway is
+  applicable
 
 ## Goals
 
 - Give Ana a way to use Gateway API without having to explicitly specify a
-  Gateway for every Route, ideally without mutating Routes.
+  Gateway for every Route, ideally without mutating Routes. (In other words,
+  give Ana an easy way to create a defaulted Route.)
+
+- Give Ana an easy way to define the scope for a defaulted Route.
 
-- Give Ana an easy way to determine which Gateway is the default, and which of
-  her Routes are bound to it.
+- Give Ana an easy way to determine which default Gateways are present in the
+  cluster, if any, and which of her Routes are currently bound to these
+  Gateways.
 
-- Continue supporting multiple Gateways in a cluster, while allowing exactly
-  one of them to be the default Gateway.
+- Continue supporting multiple Gateways in a cluster, while allowing zero or
+  more of them to be configured as default Gateways.
 
-- Allow [Chihiro] to retain control over which Gateway is the default, so that
-  they can ensure that it meets their requirements for security, performance,
-  and other operational concerns.
+- Allow [Chihiro] to retain control over which Gateways accept defaulted
+  Routes, so that they can ensure that all Gateways meet their requirements
+  for security, performance, and other operational concerns.
 
-- Allow Chihiro to choose not to provide a default Gateway.
+- Allow Chihiro to choose not to provide any default Gateways at all.
 
-- Allow Chihiro to rename, reconfigure, or replace the default Gateway at
+- Allow Chihiro to define the scope of a default Gateway.
+
+- Allow Chihiro to rename, reconfigure, or replace any default Gateway at
   runtime.
 
-  - If Chihiro renames the default Gateway, Routes using the default Gateway
-    MUST remain bound to the new default Gateway. Ana shouldn't need to go
-    recreate all her Routes just because Chihiro is being indecisive.
+  - While Kubernetes does not allow renaming a resource, Chihiro MUST be able
+    to duplicate a default Gateway under a new name, then remove the old
+    default Gateway, without disrupting routing. Ana MUST NOT need to go
+    update all her Routes just because Chihiro is being indecisive about
+    naming.
 
-  - Determine how (or if) to signal changes in functionality if the default
-    Gateway implementation is changed. For example, suppose that Chihiro
-    switches the default Gateway from an implementation that supports the
+  - Determine how (or if) to signal changes in functionality if a default
+    Gateway's implementation is changed. For example, suppose that Chihiro
+    switches a default Gateway from an implementation that supports the
     `HTTPRoutePhaseOfTheMoon` filter to an implementation that does not.
 
     (Note that this problem is not unique to default Gateways; it affects
     explicitly-named Gateways as well.)
 
-- Allow Chihiro to control which Routes may bind to the default Gateway, and
-  to enumerate which Routes are currently bound to the default Gateway.
+- Allow Chihiro to control which Routes may bind to a default Gateway, and to
+  enumerate which Routes are currently bound to a default Gateway.
 
 - Support easy interoperation with common CI/CD and GitOps workflows.
 
@@ -63,20 +99,11 @@ she doesn't have to explicitly name, and can simply trust to exist.
 
 ## Non-Goals
 
-- Support multiple "default" Gateways in a single cluster. If Ana has to make
-  a choice about which Gateway she wants to use, she'll need to be explicit
-  about that.
-
-  Loosening this restriction later is a possibility. For example, we may later
-  want to consider allowing a default Gateway per namespace, or a default
-  Gateway per implementation running in a cluster. However, these examples are
-  not in scope for this GEP, in order to have a fighting chance of getting
-  functionality into Gateway API 1.4.
+- Allow Ana to override Chihiro's choices for default Gateways for a given
+  Route without explicitly specifying the Gateway: a Route can either be
+  defaulted, or it MUST specify a Gateway explicitly.
 
-- Allow Ana to override Chihiro's choice for the default Gateway for a given
-  Route without explicitly specifying the Gateway.
-
-- Require that every possible routing use case be met by a Route using the
+- Require that every possible routing use case be met by a Route using a
   default Gateway. There will be a great many situations that require Ana to
   explicitly choose a Gateway; the existence of a default Gateway is not a
   guarantee that it will be correct for any given use case.
@@ -112,37 +139,70 @@ Ian, the Gateway is a first-class thing that they think about regularly, while
 to Ana, it's an implementation detail that she doesn't care about. Neither
 point of view is wrong, but they are in tension with each other.
 
+In practice, the trick is to find a usable balance between explicitness and
+simplicity, while managing ambiguity. A good example is the humble URL, where
+the port number is not always explicit, but it _is_ always unambiguous.
+Requiring everyone to type `:80` or `:443` at the end of the host portion of
+every URL wouldn't actually help anyone, though allowing it to be specified
+explicitly when needed definitely does help people.
+
 ### Prior Art
 
-This is very much not a new problem: there are many other systems out there
-where being unambiguous is crucial, but where being completely explicit is a
-burden. One of the simplest examples is the humble URL, where the port number
-is not always explicit, but it _is_ always unambiguous. Requiring everyone to
-type `:80` or `:443` at the end of the host portion of every URL wouldn't
-actually help anyone, though allowing it to be specified explicitly when
-needed definitely does help people.
+- **Ingress**
+
+   The Ingress resource is the most obvious example of prior art: it permitted
+   specifying a default IngressClass, allowing users to create Ingress
+   resources that didn't specify the IngressClass explicitly. As with a great
+   many things in the Ingress API, this caused problems:
+
+   1. Ingress never defined how conflicts between multiple Ingress resources
+      should be handled. Many (most?) implementations merged conflicting
+      resources, which is arguably the worst possible choice.
+
+   2. Ingress also never defined a way to allow users to see which IngressClass
+      was being used by a given Ingress resource, which made it difficult for
+      users to understand what was going on if they were using the default
+      IngressClass.
 
-The Ingress resource, of course, is another example of prior art: it permitted
-specifying a default IngressClass, allowing users to create Ingress resources
-that didn't specify the IngressClass explicitly. As with a great many things
-in the Ingress API, this caused problems:
+   (Oddly enough, Ingress' general lack of attention to separation of concerns
+   wasn't really one of the problems here, since IngressClass was a separate
+   resource.)
 
-1. Ingress never defined how conflicts between multiple Ingress resources
-   should be handled. Many (most?) implementations merged conflicting
-   resources, which is arguably the worst possible choice.
+- **Emissary Mapping**
 
-2. Ingress also never defined a way to allow users to see which IngressClass
-   was being used by a given Ingress resource, which made it difficult for
-   users to understand what was going on if they were using the default
-   IngressClass.
+  Emissary-ingress turns this idea on its head: it assumes that app developers
+  will almost never care about which specific Emissary they're using, and will
+  instead only care about the hostnames and ports involved.
 
-(Oddly enough, Ingress' general lack of attention to separation of concerns
-wasn't really one of the problems here, since IngressClass was a separate
-resource.)
+  In Emissary:
 
-It's rare to find systems that are completely explicit or completely implicit:
-in practice, the trick is to find a usable balance between explicitness and
-simplicity, while managing ambiguity.
+  - a Listener resource defines which ports and protocols are in play;
+  - a Host resource defines hostnames, TLS certificates, etc.;
+  - a Mapping resource is roughly analogous to a Route.
+
+  The Listener resource has selectors to control which Hosts it will claim;
+  Mappings, though, are claimed by Hosts based on the hostname that the
+  Mapping specifies. In other words, Mappings are not bound to a Listener
+  explicitly, but rather are bound to a Listener implicitly based on the
+  hostname that the Mapping specifies. There is no way to _explicitly_ specify
+  which Listener a Mapping wants to be claimed by.
+
+  This is obviously a very different model from Gateway API, shifting almost
+  all the work of controlling route binding away from the application
+  developer onto the cluster operator.
+
+- **Service**
+
+   We could also consider a Service of `type: LoadBalancer` as a kind of prior
+   art: in many cases, Ana can directly create these Services and use them to
+   provide direct, completely unmediated access to a workload, without
+   worrying about the specifics of how her cluster provider implements them.
+
+   Service's major disadvantages here are that it doesn't support Layer 7
+   functionality, and that each Service of type `LoadBalancer` has direct
+   costs in many cases. In other words, Service allows Ana to rely on the
+   cluster provider to create the load balancer, while forcing Ana to shoulder
+   the burden of basically everything else.
 
 ### Debugging and Visibility
 
@@ -156,15 +216,16 @@ Ana has easy access to this information, and that it's clear enough for her to
 understand, is clearly important for many more reasons than just default
 Gateways.
 
+[Ana]: https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ana
 [Chihiro]: https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#chihiro
 [Ian]: https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ian
 
 ## API
 
-Most of the API work for this GEP is TBD at this point. The challenge is to
-find a way to allow Ana to use Routes without requiring her to specify the
-Gateway explicitly, while still allowing Chihiro and Ian to retain control
-over the Gateway and its configuration.
+The main challenge in the API design is to find a way to allow Ana to use
+Routes without requiring her to specify the Gateway explicitly, while still
+allowing Chihiro and Ian to retain control over Gateways and their
+configurations.
 
 An additional concern is CD tools and GitOps workflows. In very broad terms,
 these tools function by applying manifests from a Git repository to a
@@ -184,15 +245,371 @@ Gateway controller write a new `parentRefs` stanza to the resource.
 There has been (much!) [discussion] about whether the ideal API for this
 feature will mutate the `parentRefs` of a Route using a default Gateway to
 reflect the Gateway chosen, or whether it should not, relying instead on the
-`status` stanza to carry this information. This is obviously a key point that
-will need resolution before this GEP can graduate.
+`status` stanza to carry this information. Ultimately, mutating the `spec` of
+a Kubernetes resource introduces complexity which we should avoid if it's not
+required. Since we can gracefully provide default-Gateway functionality
+without mutating `parentRefs`, we will rely on `status` instead of mutating
+`parentRefs`.
 
 [discussion]: https://github.com/kubernetes-sigs/gateway-api/pull/3852#discussion_r2140117567
 
 ### Gateway for Ingress (North/South)
 
+There are three main aspects to the API design for default Gateways:
+
+1. Giving Ana a way to indicate that a Route should be defaulted.
+
+2. Giving Chihiro a way to control which Gateways (if any) will accept
+   defaulted Routes.
+
+3. Give anyone with read access to Routes (Ana, Chihiro, or Ian) a way to
+   enumerate which Routes are bound to the default Gateways.
+
+We will describe each of these aspects in turn, laying out changes to Gateway
+API behaviors and resources that are necessary to support them. **Any behavior
+not explicitly discussed in this GEP is intended to remain unchanged;** the
+GEP covers **all** intended changes to Gateway API behavior.
+
+#### 1. Creating a Defaulted Route
+
+Since Ana must be able to choose whether a Route is defaulted or not, marking
+a Route as defaulted must be an active configuration step she takes, rather
+than any kind of implicit behavior. To that end, the `CommonRouteSpec`
+resource will gain a new field, `useDefaultGateway`, which defines the
+_scope_ for the defaulted Route:
+
+```go
+// GatewayDefaultScope defines the set of default scopes that a Gateway
+// can claim. At present the only supported scope is "All".
+type GatewayDefaultScope string
+
+const (
+  // GatewayDefaultScopeAll indicates that a Gateway can claim absolutely
+  // any Route asking for a default Gateway.
+  GatewayDefaultScopeAll GatewayDefaultScope = "All"
+)
+
+type CommonRouteSpec struct {
+    // ... other fields ...
+    useDefaultGateway GatewayDefaultScope `json:"useDefaultGateway,omitempty"`
+}
+```
+
+For Ana to indicate that a Route should use a default Gateway, she MUST set
+the Route's `spec.useDefaultGateway` to the desired scope:
+
+```yaml
+...
+spec:
+  useDefaultGateway: All
+```
+
+A defaulted Route MUST be accepted only by Gateways that have been configured
+with a matching `spec.useDefaultGateway` scope.
+
+A Route MAY include explicit `parentRefs` in addition to setting
+`spec.useDefaultGateway`. In this case, the Route will be a candidate for
+being bound to default Gateways, but it will also be bound to its
+explicitly-specified `parentRefs`. This allows Ana to create a single Route
+that handles N/S traffic via the default Gateways and also handles E/W traffic
+via a Service, for example.
+
+All other characteristics of a defaulted Route MUST behave the same as if all
+default Gateways were explicitly specified in `parentRefs`.
+
+##### Examples
+
+**Simple N/S Route**: The following HTTPRoute would route _all_ HTTP traffic
+arriving at any default Gateway to `my-service` on port 80:
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: my-route
+spec:
+  useDefaultGateway: All
+  rules:
+  - backendRefs:
+    - name: my-service
+      port: 80
+```
+
+**N/S and E/W Route**: The following HTTPRoute would be bound to both any
+default Gateways and to a Service named `face` in the `faces` namespace,
+permitting a single Route to handle both N/S traffic (via the default Gateway)
+and E/W traffic (via the Service):
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: ns-ew-route
+spec:
+  useDefaultGateway: All
+  parentRefs:
+  - kind: Service
+    name: face
+    namespace: faces
+  rules:
+  - backendRefs:
+    - name: face
+      port: 80
+```
+
+**Multiple Gateways**: A defaulted Route MAY both set `useDefaultGateway` and
+name other Gateways in `parentRefs`, although this is not expected to be
+common in practice:
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: multi-gateway-route
+spec:
+  useDefaultGateway: All
+  parentRefs:
+  - kind: Gateway
+    name: my-gateway
+    namespace: default
+  rules:
+  - backendRefs:
+    - name: my-service
+      port: 80
+```
+
+##### `status` for a Defaulted Route
+
+When a defaulted Route is claimed by a default Gateway, the Gateway MUST use
+`status.parents` to announce that it has claimed the Route, for example:
+
+```yaml
+status:
+  parents:
+  - name: my-default-gateway
+    namespace: default
+    controllerName: gateway.networking.k8s.io/some-gateway-controller
+    conditions:
+    - type: Accepted
+      status: "True"
+      lastTransitionTime: "2025-10-01T12:00:00Z"
+      message: "Route is bound to default Gateway"
+```
+
+##### Other Considerations
+
+A default Gateway MUST NOT modify the `parentRefs` of a defaulted Route to
+indicate that the Route has been claimed by a default Gateway. This becomes
+important if the set of default Gateways changes, or (in some situations) if
+GitOps tools are in play.
+
+If there are no default Gateways in the cluster, `spec.useDefaultGateway` MUST
+be treated as if it were set to `false` in all Routes, parallel to the
+situation where a Route specifies a Gateway by name, but no Gateway of that
+name exists in the cluster.
+
+#### 2. Controlling which Gateways accept Defaulted Routes
+
+Since Chihiro must be able to control which Gateways accept defaulted Routes,
+configuring a Gateway to accept defaulted Routes must be an active
+configuration step taken by Chihiro, rather than any kind of implicit
+behavior. To that end, the Gateway resource will gain a new field,
+`spec.defaultScope`:
+
+```go
+type GatewaySpec struct {
+    // ... other fields ...
+    DefaultScope GatewayDefaultScope `json:"defaultScope,omitempty"`
+}
+```
+
+Again, the only currently-defined scope is `All`.
+
+If `spec.defaultScope` is set, the Gateway MUST claim Routes that have set
+`spec.useDefaultGateway` to a matching value (subject to the usual Gateway API
+rules about which Routes may be bound to a Gateway), and it MUST update its
+own `status` with a `condition` of type `DefaultGateway` and `status` true to
+indicate that it is a default Gateway and what its scope is, for example:
+
+```yaml
+status:
+  conditions:
+  - type: DefaultGateway
+    status: "True"
+    lastTransitionTime: "2025-10-01T12:00:00Z"
+    message: "Gateway has default scope All"
+```
+
+If `spec.defaultScope` is not present, the Gateway MUST NOT claim Routes that
+do not name it specifically in `parentRefs`, and it MUST NOT set the
+`DefaultGateway` condition in its `status`.
+
+##### Access to a Default Gateway
+
+The rules for which Routes may bind to a Gateway do not change for a default
+Gateway. In particular, if a default Gateway should accept Routes from other
+namespaces, then it MUST include the appropriate `AllowedRoutes` definition,
+and without such an `AllowedRoutes`, a default Gateway MUST accept only Routes
+from its own namespace.
+
+##### Behavior with No Default Gateway
+
+If no Gateway has `spec.defaultScope` set, then all Gateways MUST ignore
+`spec.useDefaultGateway` in all Routes. A Route will be bound to only those Gateways that it specifically names in `parentRefs` entries.
+
+##### Deleting a Default Gateway
+
+Deleting a default Gateway MUST behave the same as deleting any other Gateway:
+all Routes that were bound to that Gateway MUST be unbound, and the `Accepted`
+conditions in the `status` of those Routes SHOULD be removed.
+
+##### Multiple Default Gateways
+
+Support for multiple default Gateways in a cluster was not one of the original
+goals of this GEP. However, allowing Chihiro full control over which Gateways
+accept defaulted Routes - including being able to change the set of default
+Gateways at runtime, without requiring downtime - has always been a goal, and
+this turns out to require support for multiple default Gateways.
+
+Kubernetes itself will not prevent setting `spec.defaultScope` on multiple
+Gateways in a cluster, and it also doesn't support any atomic swap mechanisms.
+If we want to enforce only a single default Gateway, the Gateway controllers
+will have to implement that enforcement logic. There are three possible
+options here.
+
+1. Don't bother with any enforcement logic.
+
+    In this case, a Route that sets `spec.useDefaultGateway` would be bound to
+    _all_ Gateways that have `spec.defaultScope` set a matching scope. Since
+    Gateway API already allows a Route to be bound to multiple Gateways, and
+    the Route `status` is already designed for it, this should function
+    without difficulty.
+
+2. Treat multiple Gateways with `spec.defaultScope` set as if no Gateway has
+   `spec.defaultScope` set.
+
+    If we assume that all Gateway controllers in a cluster can see all the
+    Gateways in the cluster, then detecting that multiple Gateways have
+    `spec.defaultScope` set is relatively straightforward.
+
+    In this case, every Gateway with `spec.defaultScope` set would ignore it,
+    with the final effect being the same as if no Gateway had
+    `spec.defaultScope` set: all Gateways would ignore
+    `spec.useDefaultGateway` in all Routes, and each Gateway would only accept
+    Routes that explicitly named it in `parentRefs`.
+
+    Each Gateway with `spec.defaultScope` set would also update its `status`
+    with a `condition` of type `DefaultGateway` and `status` false to indicate
+    that it is not the default Gateway, for example:
+
+    ```yaml
+    status:
+      conditions:
+      - type: DefaultGateway
+        status: "False"
+        lastTransitionTime: "2025-10-01T12:00:00Z"
+        message: "Multiple Gateways are marked as default"
+    ```
+
+3. Perform conflict resolution as with Routes.
+
+    In this case, the oldest Gateway with `spec.defaultScope` set would be
+    considered the only default Gateway. That oldest Gateway would be the only
+    one that honors `spec.useDefaultGateway` in Routes, and all other Gateways
+    with `spec.defaultScope` set would ignore `spec.useDefaultGateway` in
+    every Route.
+
+    The oldest default Gateway would update its `status` to reflect that it
+    the default Gateway; all other Gateways with `spec.defaultScope` set to
+    `true` will update their `status` as in Option 2.
+
+Unfortunately, option 2 will almost certainly cause downtime in any case where
+Chihiro wants to change the implementation behind a default Gateway:
+
+- If Chihiro deletes the old Gateway resource before creating the new one,
+  then all routes using that Gateway will be unbound during the time between
+  deletion and recreation, resulting in errors for any requests using those
+  Routes.
+
+- If Chihiro creates the new Gateway resource before deleting the old one,
+  then all Routes using the old default Gateway will still be unbound during
+  the time that both Gateways exist.
+
+Option 3 gives Chihiro a way to change the default Gateway without downtime:
+when they create the new default Gateway resource, it will not take effect
+until the old default Gateway resource is deleted. However, it doesn't give
+Chihiro any way to test the Routes through the new default Gateway before
+deleting the old Gateway.
+
+Reluctantly, we must therefore conclude that option 1 is the only viable
+choice. Therefore: Gateways MUST NOT attempt to enforce a single default
+Gateway, and MUST allow Routes that set `spec.useDefaultGateway` to bind to
+_all_ Gateways that have `spec.defaultScope` set a matching scope. This is
+simplest to implement, it permits zero-downtime changes to the default
+Gateway, it allows for testing of the new default Gateway before the old one
+is deleted, and it doesn't cause trouble with respect to security posture
+(since Ana already accepts that she's giving up some control over how her
+Routes are handled when she's using default Gateways).
+
+##### Changes in Functionality
+
+If Chihiro changes a default Gateway to a different implementation that does
+not support all the functionality of the previous default Gateway, then the
+Routes that were bound to the previous default Gateway will no longer function
+as expected. This is not a new problem: it already exists when Ana changes a
+Route's `parentRefs`, or when Chihiro changes the implementation of a Gateway
+that is explicitly specified in a Route's `parentRefs`.
+
+At present, we do not propose any solution to this problem, other than to note
+that `gwctl` or similar tools SHOULD be able to show Ana not just the Gateways
+to which a Route is bound, but also the features supported by those Gateways.
+This will at least give Ana some visibility into whether she's trying to use
+Gateways that don't support a feature that she needs. This is a definitely an
+area for future work, and it is complicated by the fact that Ana may not have
+access to read Gateway resources in the cluster at all.
+
+##### Listeners, ListenerSets, and Merging
+
+Setting `spec.defaultScope` on a Gateway affects which Routes will bind to the
+Gateway, not where the Gateway listens for traffic. As such, setting
+`spec.defaultScope` MUST NOT alter a Gateway's behavior with respect to
+Listeners, ListenerSets, or merging.
+
+In the future, we may want to consider allowing default ListenerSets rather
+than only default Gateways, but that is not in scope for this GEP. Even if it
+is considered later, the guiding principle SHOULD be that `spec.defaultScope`
+SHOULD NOT affect where a Gateway listens for traffic or whether it can be
+merged with other Gateways.
+
+#### 4. Enumerating Routes Bound to Default Gateways
+
+To enumerate Routes bound to the default Gateways, any of Ana, Chihiro, or Ian
+can look for Routes that set `spec.useDefaultGateway` to `true`, and then
+check the `status.parents` of those Routes to see if the Route has been
+claimed. Since this will also show _which_ Gateways have claimed a given
+defaulted Route, it neatly solves the problem of allowing Ana to determine
+which default Gateway(s) her Route is using even if she doesn't have RBAC to
+query Gateway resources directly.
+
+While this is possible with `kubectl get -o yaml`, it's not exactly a friendly
+user experience, so adding this functionality to a tool like `gwctl` would be
+a dramatic improvement. In fact, looking at the `status` of a Route is very
+much something that we should expect any user of Gateway API to do often,
+whether or not default Gateways are in play; `gwctl` or something similar
+SHOULD be able to show her which Routes are bound to which Gateways in every
+case, not just with default Gateways.
+
 ### Gateway For Mesh (East/West)
 
+Mesh traffic is defined by using a Service as a `parentRef` rather than a
+Gateway. As such, there is no case where a default Gateway would be used for
+mesh traffic.
+
+As noted above, a Route MAY both set `spec.useDefaultGateway` _and_ include a
+`Service` `parentRef` entry, allowing a single Route to handle both N/S and
+E/W traffic. In this case, the Route will be bound to both the default Gateway
+and the mesh, and the `status` will show both parents.
+
 ## Conformance Details
 
 #### Feature Names
@@ -204,14 +621,36 @@ not seem like a good choice.
 
 ### Conformance tests
 
+TBD.
+
 ## Alternatives
 
-A possible alternative API design is to modify the behavior of Listeners or
-ListenerSets; rather than having a "default Gateway", perhaps we would have
-"[default Listeners]". One challenge here is that the Route `status` doesn't
-currently expose information about which Listener is being used, though it
-does show which Gateway is being used.
+- A possible alternative API design is to modify the behavior of Listeners or
+  ListenerSets; rather than having a "default Gateway", perhaps we would have
+  "[default Listeners]". One challenge here is that the Route `status` doesn't
+  currently expose information about which Listener is being used, though it
+  does show which Gateway is being used.
 
 [default Listeners]: https://github.com/kubernetes-sigs/gateway-api/pull/3852#discussion_r2149056246
 
+- We could define the default Gateway as a Gateway with a magic name, e.g.
+  "default". This doesn't actually make things that much simpler for Ana
+  (she'd still have to specify `parentRefs`), and it raises questions about
+  Chihiro's ability to control which Routes can bind to the default Gateway,
+  as well as how namespacing would work -- it's especially unhelpful for Ana
+  if she has to know the namespace of the default Gateway in order to use it.
+
+  (Also, this is a breaking change if Chihiro has already created a
+  non-default Gateway with whatever name we choose to use for the convention.)
+
+- A default Gateway could overwrite a defaulted Route's `parentRefs` to point
+  to the default Gateway. The main challenge with this approach is that once
+  the `parentRefs` are overwritten, it's no longer possible to know what Ana
+  originally intended. Using the `status` to indicate that the Route is bound
+  to the default Gateway instead both preserves Ana's original intent and also
+  makes it possible to change the default Gateway without requiring Ana to
+  recreate all her Routes.
+
 ## References
+
+TBD.
diff --git a/geps/gep-3793/metadata.yaml b/geps/gep-3793/metadata.yaml
index 060426f0..db611f59 100644
--- a/geps/gep-3793/metadata.yaml
+++ b/geps/gep-3793/metadata.yaml
@@ -2,7 +2,7 @@ apiVersion: internal.gateway.networking.k8s.io/v1alpha1
 kind: GEPDetails
 number: 3793
 name: Default Gateways
-status: Provisional
+status: Implementable
 # Any authors who contribute to the GEP in any way should be listed here using
 # their GitHub handle.
 authors:
diff --git a/geps/gep-3798/index.md b/geps/gep-3798/index.md
index 84b4a603..16080b1e 100644
--- a/geps/gep-3798/index.md
+++ b/geps/gep-3798/index.md
@@ -1,13 +1,26 @@
 # GEP-3798: Client IP-Based Session Persistence
 
 * Issue: [#3798](https://github.com/kubernetes-sigs/gateway-api/issues/3798)
-* Status: Provisional
+* Status: Deferred
 
 (See [status definitions](../overview.md#gep-states).)
 
 ## Notes and Disclaimers
 
-* This is currently targeting release as `Experimental` in [v1.4.0](https://github.com/kubernetes-sigs/gateway-api/milestone/22). However there was notable concern in [PR#3844](https://github.com/kubernetes-sigs/gateway-api/pull/3844) that it may be difficult to get multiple implementations who will be ready to implement this and move it forward. As such, the primary focus at this point should be finding representatives of implementations who may be interested in implementing this. Otherwise, this GEP may need to be `Deferred` and revisited as part of a later release.
+* **DEFERRED**: This originally targeted release as `Experimental` in [v1.4.0].
+  Notably (in [PR#3844]) there was concern that it may be difficult to get
+  multiple implementations to support this. During the release cycle, this GEP
+  was not able to meet the timeline requirements to progress, so it is now
+  considered deferred. If anyone is interested in picking this back up, it will
+  need to be re-submitted for consideration in a future release with a written
+  plan about how it will achieve implementation from multiple implementations.
+  If this remains in deferred state for a prolonged period, it may eventually
+  be moved to `Withdrawn`, or moved into the alternatives considered for
+  [GEP-1619].
+
+[v1.4.0]:https://github.com/kubernetes-sigs/gateway-api/milestone/22
+[PR#3844]:https://github.com/kubernetes-sigs/gateway-api/pull/3844
+[GEP-1619]:https://gateway-api.sigs.k8s.io/geps/gep-1619/
 
 ## TLDR
 
diff --git a/geps/gep-3798/metadata.yaml b/geps/gep-3798/metadata.yaml
index e7d33a7c..85a47289 100644
--- a/geps/gep-3798/metadata.yaml
+++ b/geps/gep-3798/metadata.yaml
@@ -2,7 +2,7 @@ apiVersion: internal.gateway.networking.k8s.io/v1alpha1
 kind: GEPDetails
 number: 3798
 name: Client IP-Based Session Persistence
-status: Provisional
+status: Deferred
 # Any authors who contribute to the GEP in any way should be listed here using
 # their GitHub handle.
 authors:
diff --git a/geps/gep-3949/index.md b/geps/gep-3949/index.md
new file mode 100644
index 00000000..26f5f205
--- /dev/null
+++ b/geps/gep-3949/index.md
@@ -0,0 +1,539 @@
+# GEP-3949: Mesh Resource
+
+* Issue: [#3949](https://github.com/kubernetes-sigs/gateway-api/issues/3949)
+* Status: Implementable
+
+(See [status definitions](../overview.md#gep-states).)
+
+[Chihiro]: https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#chihiro
+[Ian]: https://gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ian
+[Ana]: https//gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ana
+
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
+"SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this
+document are to be interpreted as described in BCP 14 ([RFC8174]) when, and
+only when, they appear in all capitals, as shown here.
+
+[RFC8174]: https://www.rfc-editor.org/rfc/rfc8174
+
+## User Story
+
+**[Chihiro] and [Ian] would like a Mesh resource,
+parallel to the Gateway resource,
+that allows them to
+supply mesh-wide configuration
+and
+shows what features
+a given mesh implementation supports.**
+
+## Background
+
+Gateway API has long had a GatewayClass resource
+that represents a class of Gateways
+that can be instantiated in a cluster.
+GatewayClass both
+allows configuring the class as a whole
+and provides a way for [Chihiro] and [Ian] to see
+what features Gateways in that class support.
+We have,
+to date,
+avoided such a resource for meshes,
+but as we work on
+improving mesh conformance tests and reports
+and start work on
+supporting Out-of-Cluster Gateways (OCGs),
+we will need ways to
+show what features a given mesh implementation supports
+and represent mesh-wide configuration.
+
+This GEP therefore defines a Mesh resource
+which represents a running instance of a service mesh,
+allowing [Chihiro] and [Ian] to
+supply mesh-wide configuration,
+and allowing the mesh implementation
+to indicate what features it supports.
+
+Unlike Gateways, we do not expect
+multiple instances of meshes to be instantiated
+in a single cluster.
+This implies that a MeshClass resource is not needed;
+instead, we will simply define a Mesh resource.
+
+## Goals
+
+- Define a Mesh resource
+  that allows for
+  mesh-wide configuration
+  and feature discovery.
+
+- Avoid making it more difficult for [Chihiro] and [Ian]
+  to adopt a mesh
+  (or to experiment with adopting a mesh).
+
+## Non-Goals
+
+- Support meshes interoperating with each other.
+
+    As always,
+    we will not rule out future work
+    in this area,
+    but it is out of scope
+    for this GEP.
+
+- Support off-cluster gateways.
+
+    This is covered in a separate GEP
+    and will not be discussed here.
+
+- Change GAMMA's position on
+  multiple meshes running simultaneously
+  in a single cluster.
+
+    GAMMA has always taken the position
+    that multiple meshes running simultaneously
+    in a single cluster
+    is not an explicit goal, but neither is it forbidden.
+    This GEP does not change that position.
+
+## API
+
+The purpose
+of the Mesh resource
+is to support both
+mesh-wide configuration
+as well as feature discovery.
+However,
+as of the writing of this GEP,
+there is
+no mesh-wide configuration
+that is portable across implementations.
+Therefore,
+the Mesh resource
+is currently pretty simple:
+
+```yaml
+apiVersion: gateway.networking.x-k8s.io/v1alpha1
+kind: XMesh
+metadata:
+  name: one-mesh-to-mesh-them-all
+spec:
+  # required, must be domain-prefixed
+  controllerName: one-mesh.example.com/one-mesh
+  parametersRef:
+    # optional ParametersReference
+    ...
+```
+
+- The Mesh resource is cluster-scoped,
+  so there is no `metadata.namespace` field.
+
+- Although we call this the Mesh resource,
+  as an experimental API
+  it must be named XMesh
+  in the `gateway.networking.x-k8s.io` API group.
+
+    When the API graduates to standard,
+    it will be renamed to `Mesh`
+    in the `gateway.networking.k8s.io` API group.
+
+- The `controllerName` field
+  is analogous to
+  the `controllerName` field
+  in the GatewayClass resource:
+  it defines the name
+  of the mesh implementation
+  that is responsible for
+  this Mesh resource.
+
+    A given mesh implementation will define its controller name
+    at build time.
+    It MUST be a domain-prefixed path,
+    for example `linkerd.io/linkerd` or `istio.io/istio`.
+    It MUST NOT be empty.
+    It MAY be configurable at runtime,
+    although this is not expected to be common.
+
+    Although we expect
+    that there will be
+    only one mesh
+    in a given cluster, the
+    `controllerName` field
+    MUST be supplied,
+    and a given mesh implementation
+    MUST ignore
+    a Mesh resource
+    that does not have
+    a `controllerName` field
+    that matches its own name.
+
+- The `parametersRef` field
+  is analogous to
+  the `parametersRef` field
+  in the GatewayClass resource:
+  it allows optionally specifying
+  a reference to a resource
+  that contains configuration
+  specific to the mesh
+  implementation.
+
+### `status`
+
+The `status` stanza
+of the Mesh resource
+is used to indicate
+whether the Mesh resource
+has been accepted by
+a mesh implementation,
+whether the mesh is
+ready to use,
+and
+what features
+the mesh supports.
+
+```yaml
+apiVersion: gateway.networking.x-k8s.io/v1alpha1
+kind: XMesh
+metadata:
+  name: one-mesh-to-mesh-them-all
+spec:
+  controllerName: one-mesh.example.com/one-mesh
+status:
+  conditions:
+    # MUST include Accepted condition if the Mesh resource is active.
+    - type: Accepted  # Becomes true when the controller accepts the Mesh resource
+      status: "True"
+      reason: Accepted
+      lastTransitionTime: "2023-10-01T12:00:00Z"
+      message: Mesh resource accepted by one-mesh v1.2.3 in namespace one-mesh
+    ...
+  supportedFeatures:
+    # List of SupportedFeature
+    - name: MeshHTTPRoute
+    - name: MeshConsumerRoute
+    - name: OffClusterGateway
+    ...
+```
+
+Although GAMMA does not fully support multiple meshes
+running in the same cluster at the same time,
+meshes still MUST provide
+human-readable information
+in the `Accepted` condition
+about which mesh instance
+has claimed a given Mesh resource.
+This information is meant to be used
+by [Chihiro] and [Ian] as confirmation
+that the mesh instance
+is doing what they expect it to do.
+
+Mesh implementations MUST
+reject Mesh resources in which `spec.parametersRef`
+references a resource that does not exist
+or is not supported by the mesh implementation,
+setting the `Reason` to `InvalidParameters`.
+
+The mesh implementation
+MUST set `status.SupportedFeatures`
+to indicate which features
+the mesh supports.
+
+### Life Cycle
+
+One of the explicit goals of this GEP
+is to avoid making it more difficult for [Chihiro] and [Ian]
+to adopt a mesh.
+In turn, this implies that we MUST NOT require [Chihiro] or [Ian]
+to manually create a Mesh resource in order to use a mesh.
+
+The simplest way to achieve this is
+for the mesh implementation to create a Mesh resource
+when it starts up,
+if one does not already exist
+with a matching `controllerName` field.
+This raises questions around
+what the Mesh resource should be named,
+and how the mesh implementation can avoid overwriting
+any modifications [Chihiro] or [Ian] make
+to the Mesh resource after it is created.
+
+To manage these concerns
+while still minimizing added friction,
+mesh implementations MUST define a default `metadata.name`
+for the Mesh resource they will look for,
+and SHOULD allow overriding this name at install time.
+This default name SHOULD be
+an obvious derivative of the mesh implementation name,
+such as "linkerd" or "istio";
+its purpose is to make it easy for [Chihiro] and [Ian]
+to find the Mesh resource
+while also allowing for the possibility
+that there will need to be more than one
+Mesh resource in a cluster.
+
+At startup, then:
+
+- The mesh implementation MUST look for a Mesh resource
+  with the expected `metadata.name` field.
+
+- If no Mesh resource exists with the expected `metadata.name`,
+  the implementation MUST create a Mesh resource
+  with the expected `metadata.name`
+  and `spec.controllerName` fields.
+
+  - The mesh MUST NOT set any other fields
+    in the `spec` of the Mesh resource
+    that it creates.
+
+    In particular, the mesh MUST NOT set `parametersRef`
+    when it creates the Mesh resource.
+
+- Otherwise
+  (a Mesh resource already exists with the expected `metadata.name`),
+  the implementation MUST NOT modify the `spec`
+  of that Mesh resource
+  in **any way**.
+  Instead, it MUST check the `spec.controllerName` field:
+
+  - If the Mesh resource has a matching `spec.controllerName` field:
+
+      - The implementation MUST set the `status` stanza
+        of the Mesh resource
+        to indicate whether or not it has accepted the Mesh resource
+        and, if accepted, what features the mesh supports.
+
+  - Otherwise
+    (the Mesh resource does not have
+    a matching `spec.controllerName` field):
+
+      - The implementation MUST NOT modify the Mesh resource
+        in any way,
+        and it SHOULD warn the user
+        (in whatever way is appropriate for the mesh)
+        that there is a mismatch in the Mesh resource
+
+```mermaid
+flowchart TD
+  Start{Does a Mesh resource with a matching name exist?}
+  Start -->|Yes| Match
+  Start -->|No| NoMatch
+  Match{Does the controllerName also match?}
+  Match -->|No| WarnNoModify
+  Match -->|Yes| UpdateStat
+  NoMatch[Create a new Mesh resource] --> CheckCreate
+  CheckCreate{Did creation succeed?}
+  CheckCreate -->|Yes| UpdateStat
+  CheckCreate -->|No| Warn
+  UpdateStat[Update status]
+  Warn[Warn]
+  WarnNoModify[Warn and don't modify]
+```
+
+If, at the end of this process,
+there is no Mesh resource with both
+a matching `metadata.name` and
+a matching `spec.controllerName`,
+the implementation MUST act as if
+a Mesh resource was found with a empty `spec`
+(other than the `controllerName` field).
+Optional configuration MUST remain in its default state,
+and features that require a Mesh resource
+(such as OCG support)
+MUST NOT be enabled.
+
+Obviously, if no matching Mesh resource exists,
+the mesh will not be able to publish support features,
+which may lead to assumptions
+that the mesh does not support any features.
+
+The mesh implementation MUST NOT,
+under any circumstances,
+modify the `spec` of a Mesh resource
+other than by creating a new Mesh resource
+when one does not exist.
+
+Mesh implementations SHOULD
+respond to changes in the Mesh resource
+without requiring the mesh to be restarted.
+
+### API Type Definitions
+
+```go
+// Mesh is a Cluster level resource.
+type Mesh struct {
+  metav1.TypeMeta   `json:",inline"`
+  metav1.ObjectMeta `json:"metadata,omitempty"`
+
+  // Spec defines the desired state of Mesh.
+  Spec MeshSpec `json:"spec"`
+
+  // Status defines the current state of Mesh.
+  //
+  // Implementations MUST populate status on all Mesh resources which
+  // specify their controller name.
+  //
+  // Defaults to Accepted condition with status Unknown and reason Pending.
+  Status MeshStatus `json:"status,omitempty"`
+}
+
+// MeshSpec defines the desired state of a Mesh.
+type MeshSpec struct {
+  // ControllerName is the name of the controller that is managing this
+  // Mesh. The value of this field MUST be a domain prefixed path.
+  //
+  // Example: "example.com/awesome-mesh".
+  //
+  // This field is not mutable and cannot be empty.
+  //
+  // Support: Core
+  //
+  // +kubebuilder:validation:XValidation:message="Value is immutable",rule="self == oldSelf"
+  ControllerName string `json:"controllerName"`
+
+  // ParametersRef is an optional reference to a resource that contains
+  // implementation-specific for this Mesh. If no implementation-specific
+  // parameters are needed, this field MUST be omitted.
+  //
+  // ParametersRef can reference a standard Kubernetes resource, i.e.
+  // ConfigMap, or an implementation-specific custom resource. The resource
+  // can be cluster-scoped or namespace-scoped.
+  //
+  // If the referent cannot be found, refers to an unsupported kind, or when
+  // the data within that resource is malformed, the Mesh MUST be rejected
+  // with the "Accepted" status condition set to "False" and an
+  // "InvalidParameters" reason.
+  //
+  // Support: Implementation-specific
+  //
+  // +optional
+  ParametersRef *ParametersReference `json:"parametersRef,omitempty"`
+}
+
+// MeshConditionType is the type for status conditions on Mesh resources.
+// This type should be used with the MeshStatus.Conditions field.
+type MeshConditionType string
+
+// MeshConditionReason defines the set of reasons that explain why a
+// particular Mesh condition type has been raised.
+type MeshConditionReason string
+
+const (
+  // This condition indicates whether the Mesh has been accepted by the
+  // controller requested in the `spec.controller` field.
+  //
+  // This condition defaults to Unknown, and MUST be set by a controller
+  // when it sees a Mesh using its controller string. The status of this
+  // condition MUST be set to True if the controller will accept the Mesh
+  // resource. Otherwise, this status MUST be set to False. If the status
+  // is set to False, the controller MUST set a Message and Reason as an
+  // explanation.
+  //
+  // Possible reasons for this condition to be true are:
+  //
+  // * "Accepted"
+  //
+  // Possible reasons for this condition to be False are:
+  //
+  // * "InvalidParameters"
+  //
+  // Controllers should prefer to use the values of MeshConditionReason
+  // for the corresponding Reason, where appropriate.
+  MeshConditionStatusAccepted MeshConditionType = "Accepted"
+
+  // This reason is used with the "Accepted" condition when the condition is
+  // true.
+  MeshConditionReasonAccepted MeshConditionReason = "Accepted"
+
+  // This reason is used with the "Accepted" condition when the Mesh
+  // was not accepted because the parametersRef field refers to
+  // * a namespaced resource but the Namespace field is not set, or
+  // * a cluster-scoped resource but the Namespace field is set, or
+  // * a nonexistent object, or
+  // * an unsupported resource or kind, or
+  // * an existing resource but the data within that resource is malformed.
+  MeshConditionReasonInvalidParameters MeshConditionReason = "InvalidParameters"
+
+  // This reason is used with the "Accepted" condition when the
+  // requested controller has not yet made a decision about whether
+  // to accept the Mesh. It is the default Reason on a new Mesh.
+  MeshConditionReasonPending MeshConditionReason = "Pending"
+)
+
+// MeshStatus is the current status for the Mesh.
+type MeshStatus struct {
+  // Conditions is the current status from the controller for
+  // this Mesh.
+  //
+  // Controllers should prefer to publish conditions using values
+  // of MeshConditionType for the type of each Condition.
+  //
+  // +optional
+  // +listType=map
+  // +listMapKey=type
+  // +kubebuilder:validation:MaxItems=8
+  // Defaults to Accepted condition with status Unknown and reason Pending.
+  Conditions []metav1.Condition `json:"conditions,omitempty"`
+
+  // SupportedFeatures is the set of features the Mesh support.
+  // It MUST be sorted in ascending alphabetical order by the Name key.
+  // +optional
+  // +listType=map
+  // +listMapKey=name
+  // <gateway:experimental>
+  // +kubebuilder:validation:MaxItems=64
+  SupportedFeatures []SupportedFeature `json:"supportedFeatures,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// MeshList contains a list of Mesh
+type MeshList struct {
+  metav1.TypeMeta `json:",inline"`
+  metav1.ListMeta `json:"metadata,omitempty"`
+  Items           []Mesh `json:"items"`
+}
+```
+
+## Conformance Details
+
+TBA.
+
+#### Feature Names
+
+No feature name is defined
+for the Mesh resource itself;
+filling out the `status` stanza
+of the Mesh resource
+is a conformance requirement,
+and is sufficient indication
+that the Mesh resource is supported.
+
+### Conformance tests
+
+TBA.
+
+## Alternatives
+
+We did not find any
+particularly compelling alternatives
+to having a Mesh resource
+to meet these needs.
+We considered having both
+MeshClass and Mesh resources,
+but decided that
+there was no clear need for both,
+and that a Mesh resource
+better served the use cases.
+
+If a MeshClass resource
+is later defined,
+the Mesh resource
+will need to be updated.
+One potential approach to such an update might be:
+
+- Add a `meshClassName` field to the Mesh resource;
+- Deprecate the `controllerName` field; and
+- Define that a Mesh resource with both fields set is invalid.
+
+## References
+
+TBA.
diff --git a/geps/gep-3949/metadata.yaml b/geps/gep-3949/metadata.yaml
new file mode 100644
index 00000000..de9c3639
--- /dev/null
+++ b/geps/gep-3949/metadata.yaml
@@ -0,0 +1,34 @@
+apiVersion: internal.gateway.networking.k8s.io/v1alpha1
+kind: GEPDetails
+number: 3949
+name: Mesh Resource
+status: Implementable
+# Any authors who contribute to the GEP in any way should be listed here using
+# their GitHub handle.
+authors:
+  - kflynn
+  - karthikbox
+relationships:
+  # obsoletes indicates that a GEP makes the linked GEP obsolete, and completely
+  # replaces that GEP. The obsoleted GEP MUST have its obsoletedBy field
+  # set back to this GEP, and MUST be moved to Declined.
+  obsoletes: {}
+  obsoletedBy: {}
+  # extends indicates that a GEP extends the linked GEP, adding more detail
+  # or additional implementation. The extended GEP MUST have its extendedBy
+  # field set back to this GEP.
+  extends: {}
+  extendedBy: {}
+  # seeAlso indicates other GEPs that are relevant in some way without being
+  # covered by an existing relationship.
+  seeAlso: {}
+# references is a list of hyperlinks to relevant external references.
+# It's intended to be used for storing GitHub discussions, Google docs, etc.
+references: {}
+# featureNames is a list of the feature names introduced by the GEP, if there
+# are any. This will allow us to track which feature was introduced by which GEP.
+# This is the value added to supportedFeatures and the conformance tests, in string form.
+featureNames: {}
+# changelog is a list of hyperlinks to PRs that make changes to the GEP, in
+# ascending date order.
+changelog: {}
diff --git a/geps/gep-91/index.md b/geps/gep-91/index.md
index 5d28c9a1..8eedb7bd 100644
--- a/geps/gep-91/index.md
+++ b/geps/gep-91/index.md
@@ -10,24 +10,37 @@
 This GEP proposes a way to validate the TLS certificate presented by the frontend client to the server
 (Gateway in this case) during a [TLS Handshake Protocol][].
 
+## Connection coalescing security issue
+
+Gateway API standard defines a `Listener` as "the concept of a logical endpoint where a Gateway accepts network connections." This statement is incorrect because once the connection is established (this applies to both HTTP and TLS traffic) it can be reused across multiple listeners sharing the same port. This might lead to bypassing client certificate validation configuration for a given `Listener`. Those concerns were raised in [GEP-3567](). To provide the best experience for gateway users and secure their applications, client certificate configuration needs to be introduced with finer granularity per-port (binding to TCP connection).
+
 ## Goals
 
 * Define an API field to specify the CA Certificate within the Gateway configuration that can be used as a trust anchor to validate the certificates presented by the client.
 This use case has been highlighted in the [TLS Configuration GEP][] under segment 1 and in the [Gateway API TLS Use Cases][] document under point 7.
+* Introduce explicit client certificate validation modes that reflect common TLS behaviors (e.g., optional vs. required client certs)
 * Ensure the configuration mitigates the authentication bypass risks associated with HTTP/2 connection coalesing as described in [GEP-3567](https://gateway-api.sigs.k8s.io/geps/gep-3567/#interaction-with-client-cert-validation).
-* Supporting a mode where validating client certificates is optional, useful for debugging and migrating to strict TLS.
 
 ## Non-Goals
 * Define other fields that can be used to verify the client certificate such as the Certificate Hash.
 
 ### API
 
-* Introduce a `FrontendValidation` field of type `FrontendTLSValidation` within [GatewayTLSConfig][] that can be used to validate the peer (frontend) with which the TLS connection is being made.
+* Introduce two new structs `TLSConfig` and `FrontendTLSValidation` allowing for the definition of certificate validation used to authenticate the peer (frontend) in a TLS connection. A new `tls` field, storing an array of `TLSConfigs`, will be added to the gateway object.
+* This new field is separate from the existing [BackendTLSPolicy][] configuration. [BackendTLSPolicy][] controls TLS certificate validation for connections *from* the Gateway to the backend service.
+This proposal adds the ability to validate the TLS certificate presented by the *client* connecting to the Gateway (the frontend).
+These two validation mechanisms operate independently and can be used simultaneously.
 * Introduce a `caCertificateRefs` field within `FrontendTLSValidation` that can be used to specify a list of CA Certificates that can be used as a trust anchor to validate the certificates presented by the client.
-* This new field is separate from the existing [BackendTLSPolicy][] configuration. [BackendTLSPolicy][] controls TLS certificate validation for connections *from* the
-  Gateway to the backend service.  This proposal adds the ability to validate the TLS certificate presented by the *client* connecting to the Gateway (the
-  frontend). These two validation mechanisms operate independently and can be used simultaneously.
-* Also introduce a `ObjectReference` structure that can be used to specify `caCertificateRefs` references.
+* Add a new `FrontendValidationModeType` enum within `FrontendTLSValidation` indicating how gateway should validate client certificates. As for now we support following values but it might change in the future:
+  1) `AllowValidOnly`
+  2) `AllowInvalidOrMissingCert`
+* Introduce a `ObjectReference` structure that can be used to specify `caCertificateRefs` references.
+* Introduce a `tls` field within the Gateway Spec to allow for a common TLS configuration to apply across all listeners.
+
+### Impact on listeners
+
+This proposal removes frontendTLSValidation from Listener's TLS configuration and introduces gateways level per port configuration. This is a breaking change for exisitng implementation which uses this feature from Experimental API.
+ Once gateway level TLS is configured (either by default or for a specific port), the TLS settings will apply to all existing and newly created Listeners that match the configuration.
 
 #### GO
 
@@ -65,50 +78,118 @@ type ObjectReference struct {
 	Namespace *Namespace `json:"namespace,omitempty"`
 }
 
-type GatewayTLSConfig struct {
-    ......
-    // FrontendValidation holds configuration information for validating the frontend (client).
-    // Setting this field will require clients to send a client certificate
-    // required for validation during the TLS handshake. In browsers this may result in a dialog appearing
-    // that requests a user to specify the client certificate.
-    // The maximum depth of a certificate chain accepted in verification is Implementation specific.
-    FrontendValidation *FrontendTLSValidation `json:"frontendValidation,omitempty"`
+// GatewayTLSConfigs stores TLS configurations for a Gateway.
+//
+// * If the `port` field in `TLSConfig` is not set, the TLS configuration applies
+//   to all listeners in the gateway. We call this `default` configuration.
+// * If the `port` field in `TLSConfig` is set, the TLS configuration applies
+//   only to listeners with a matching port. Each port requires a unique TLS configuration.
+// * Per-port configurations can override the `default` configuration.
+// * The `default` configuration is optional. Clients can apply TLS configuration
+//   to a subset of listeners by creating only per-port configurations. Listeners
+//   with a port that does not match any TLS configuration will not have
+//   `frontendValidation` set.
+type GatewayTLSConfigs = []TLSConfig
+
+// TLSConfig describes a TLS configuration that can be applied to all Gateway
+// Listeners or to all Listeners matching the Port if set.
+type TLSConfig struct {
+	// The Port indicates the Port Number to which the TLS configuration will be
+	// applied. If the field is not set the TLS Configuration will be applied to
+	// all Listeners.
+	//
+	// Support: Extended
+	//
+	// +optional
+	// <gateway:experimental>
+	Port *PortNumber
+	// FrontendValidation holds configuration information for validating the frontend (client).
+	// Setting this field will result in mutual authentication when connecting to the gateway. In browsers this may result in a dialog appearing
+	// that requests a user to specify the client certificate.
+	// The maximum depth of a certificate chain accepted in verification is Implementation specific.
+	//
+	// Each field may be overidden by an equivalent setting applied at the Listener level.
+	//
+	// Support: Extended
+	//
+	// +optional
+	// <gateway:experimental>
+	FrontendValidation *FrontendTLSValidation `json:"frontendValidation,omitempty"`
 }
 
 // FrontendTLSValidation holds configuration information that can be used to validate
 // the frontend initiating the TLS connection
 type FrontendTLSValidation struct {
-    // CACertificateRefs contains one or more references to
-    // Kubernetes objects that contain TLS certificates of
-    // the Certificate Authorities that can be used
-    // as a trust anchor to validate the certificates presented by the client.
-    //
-    // A single CA certificate reference to a Kubernetes ConfigMap
-    // has "Core" support.
-    // Implementations MAY choose to support attaching multiple CA certificates to
-    // a Listener, but this behavior is implementation-specific.
-    //
-    // Support: Core - A single reference to a Kubernetes ConfigMap
-    // with the CA certificate in a key named `ca.crt`.
-    //
-    // Support: Implementation-specific (More than one reference, or other kinds
-    // of resources).
-    //
-    // References to a resource in a different namespace are invalid UNLESS there
-    // is a ReferenceGrant in the target namespace that allows the certificate
-    // to be attached. If a ReferenceGrant does not allow this reference, the
-    // "ResolvedRefs" condition MUST be set to False for this listener with the
-    // "RefNotPermitted" reason.
-    //
-    // +kubebuilder:validation:MaxItems=8
-    // +kubebuilder:validation:MinItems=1
-    CACertificateRefs []ObjectReference `json:"caCertificateRefs,omitempty"`
+	// CACertificateRefs contains one or more references to
+	// Kubernetes objects that contain TLS certificates of
+	// the Certificate Authorities that can be used
+	// as a trust anchor to validate the certificates presented by the client.
+	//
+	// A single CA certificate reference to a Kubernetes ConfigMap
+	// has "Core" support.
+	// Implementations MAY choose to support attaching multiple CA certificates to
+	// a Listener, but this behavior is implementation-specific.
+	//
+	// Support: Core - A single reference to a Kubernetes ConfigMap
+	// with the CA certificate in a key named `ca.crt`.
+	//
+	// Support: Implementation-specific (More than one certificate in a ConfigMap with different keys or more than one reference, or other kinds of resources).
+	//
+	// References to a resource in a different namespace are invalid UNLESS there
+	// is a ReferenceGrant in the target namespace that allows the certificate
+	// to be attached. If a ReferenceGrant does not allow this reference, the
+	// "ResolvedRefs" condition MUST be set to False for this listener with the
+	// "RefNotPermitted" reason.
+	//
+	// +kubebuilder:validation:MaxItems=8
+	// +kubebuilder:validation:MinItems=1
+	CACertificateRefs []ObjectReference `json:"caCertificateRefs,omitempty"`
+
+	// FrontendValidationMode defines the mode for validating the client certificate.
+	// There are two possible modes:
+	//
+	// - AllowValidOnly: In this mode, the gateway will accept connections only if
+	//   the client presents a valid certificate. This certificate must successfully
+	//   pass validation against the CA certificates specified in `CACertificateRefs`.
+	// - AllowInvalidOrMissingCert: In this mode, the gateway will accept
+	//   connections even if the client certificate is not presented or fails verification.
+	//
+	// Defaults to AllowValidOnly.
+	//
+	// Support: Extended
+	//
+	// +optional
+	// +kubebuilder:default=AllowValidOnly
+	Mode *FrontendValidationModeType `json:"mode,omitempty"`
+}
+
+// FrontendValidationModeType type defines how a Gateway or Listener validates client certificates.
+//
+// +kubebuilder:validation:Enum=AllowValidOnly;AllowInvalidOrMissingCert
+type FrontendValidationModeType string
+
+const (
+	// AllowValidOnly indicates that a client certificate is required
+	// during the TLS handshake and MUST pass validation.
+	AllowValidOnly FrontendValidationModeType = "AllowValidOnly"
+
+	// AllowInvalidOrMissingCert indicates that a client certificate may not be
+	// presented during the handshake or the validation against CA certificates may fail.
+	AllowInvalidOrMissingCert FrontendValidationModeType = "AllowInvalidOrMissingCert"
+)
+
+type GatewaySpec struct {
+    ...
+    // TLSConfigs stores TLS configurations for a Gateway.
+    TLSConfigs GatewayTLSConfigs
 }
 
 ```
 
 #### YAML
 
+1. Setting default `frontendValidation` config.
+
 ```yaml
 apiVersion: gateway.networking.k8s.io/v1beta1
 kind: Gateway
@@ -116,6 +197,12 @@ metadata:
   name: client-validation-basic
 spec:
   gatewayClassName: acme-lb
+  tls:
+    - frontendValidation:
+        caCertificateRefs:
+        - kind: ConfigMap
+          group: ""
+          name: default-cert
   listeners:
   - name: foo-https
     protocol: HTTPS
@@ -126,11 +213,58 @@ spec:
       - kind: Secret
         group: ""
         name: foo-example-com-cert
+  - name: bar-https
+    protocol: HTTPS
+    port: 8443
+    hostname: bar.example.com
+    tls:
+      certificateRefs:
+      - kind: Secret
+        group: ""
+        name: bar-example-com-cert
+```
+
+2. Setting default and per port `frontendValidation` configs.
+
+```yaml
+apiVersion: gateway.networking.k8s.io/v1beta1
+kind: Gateway
+metadata:
+  name: client-validation-basic
+spec:
+  gatewayClassName: acme-lb
+  tls:
+    - port: 443
       frontendValidation:
         caCertificateRefs:
         - kind: ConfigMap
           group: ""
           name: foo-example-com-ca-cert
+    - frontendValidation:
+        caCertificateRefs:
+        - kind: ConfigMap
+          group: ""
+          name: default-cert
+        mode: AllowInvalidOrMissingCert
+  listeners:
+  - name: foo-https
+    protocol: HTTPS
+    port: 443
+    hostname: foo.example.com
+    tls:
+      certificateRefs:
+      - kind: Secret
+        group: ""
+        name: foo-example-com-cert
+  - name: bar-https
+    protocol: HTTPS
+    port: 8443
+    hostname: bar.example.com
+    tls:
+      certificateRefs:
+      - kind: Secret
+        group: ""
+        name: bar-example-com-cert
 ```
 
 ## Deferred
@@ -143,7 +277,7 @@ This section highlights use cases that may be covered in a future iteration of t
 
 ## Existing support in Implementations
 
-This feature is already widely supported by implementations that conform to the Gateway API. 
+This feature is already widely supported by implementations that conform to the Gateway API.
 The table below summarizes current support. Please feel free to add any implementations that are missing.
 This GEP aims to standardize this behavior as an official part of the upstream specification.
 
@@ -191,3 +325,4 @@ This GEP aims to standardize this behavior as an official part of the upstream s
 [BackendTLSPolicy]: ../../api-types/backendtlspolicy.md
 [TLS Configuration GEP]: ../gep-2907/index.md
 [Gateway API TLS Use Cases]: https://docs.google.com/document/d/17sctu2uMJtHmJTGtBi_awGB0YzoCLodtR6rUNmKMCs8/edit?pli=1#heading=h.cxuq8vo8pcxm
+[GEP-3567]: https://gateway-api.sigs.k8s.io/geps/gep-3567/
diff --git a/go.mod b/go.mod
index 82f05190..2ef20f67 100644
--- a/go.mod
+++ b/go.mod
@@ -8,32 +8,33 @@ require (
 	github.com/stretchr/testify v1.10.0
 	golang.org/x/net v0.41.0
 	golang.org/x/sync v0.16.0
-	google.golang.org/grpc v1.73.0
+	google.golang.org/grpc v1.74.2
 	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1
 	google.golang.org/protobuf v1.36.6
-	k8s.io/api v0.33.2
-	k8s.io/apiextensions-apiserver v0.33.2
-	k8s.io/apimachinery v0.33.2
-	k8s.io/client-go v0.33.2
-	k8s.io/code-generator v0.33.2
+	k8s.io/api v0.33.3
+	k8s.io/apiextensions-apiserver v0.33.3
+	k8s.io/apimachinery v0.33.3
+	k8s.io/client-go v0.33.3
+	k8s.io/code-generator v0.33.3
 	k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff
 	k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738
 	sigs.k8s.io/controller-runtime v0.21.0
 	sigs.k8s.io/controller-tools v0.18.0
 	sigs.k8s.io/structured-merge-diff/v4 v4.7.0
-	sigs.k8s.io/yaml v1.4.0
+	sigs.k8s.io/yaml v1.5.0
 )
 
 require (
 	github.com/Masterminds/goutils v1.1.1 // indirect
 	github.com/Masterminds/semver v1.5.0 // indirect
 	github.com/Masterminds/sprig v2.22.0+incompatible // indirect
+	github.com/blang/semver/v4 v4.0.0 // indirect
 	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/emicklei/go-restful/v3 v3.12.0 // indirect
 	github.com/evanphx/json-patch/v5 v5.9.11 // indirect
 	github.com/fatih/color v1.18.0 // indirect
 	github.com/fxamacker/cbor/v2 v2.7.0 // indirect
-	github.com/go-logr/logr v1.4.2 // indirect
+	github.com/go-logr/logr v1.4.3 // indirect
 	github.com/go-openapi/jsonpointer v0.21.0 // indirect
 	github.com/go-openapi/jsonreference v0.21.0 // indirect
 	github.com/go-openapi/swag v0.23.0 // indirect
@@ -66,16 +67,17 @@ require (
 	github.com/x448/float16 v0.8.4 // indirect
 	go.uber.org/multierr v1.11.0 // indirect
 	go.uber.org/zap v1.27.0 // indirect
+	go.yaml.in/yaml/v2 v2.4.2 // indirect
 	golang.org/x/crypto v0.39.0 // indirect
 	golang.org/x/mod v0.25.0 // indirect
-	golang.org/x/oauth2 v0.28.0 // indirect
+	golang.org/x/oauth2 v0.30.0 // indirect
 	golang.org/x/sys v0.33.0 // indirect
 	golang.org/x/term v0.32.0 // indirect
 	golang.org/x/text v0.26.0 // indirect
 	golang.org/x/time v0.9.0 // indirect
 	golang.org/x/tools v0.33.0 // indirect
 	golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect
 	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/go.sum b/go.sum
index 85b14c3a..7050b8ff 100644
--- a/go.sum
+++ b/go.sum
@@ -6,8 +6,12 @@ github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZC
 github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
+github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
+github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
 github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
 github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -25,8 +29,8 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
 github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
 github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
 github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
-github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
-github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
+github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
+github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
 github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
 github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
 github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
@@ -120,6 +124,14 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
 github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
+github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
+github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
+github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
+github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
+github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
+github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
+github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
 github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
 github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
@@ -144,22 +156,26 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
 go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
-go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
-go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
-go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
-go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
-go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
-go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
-go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
-go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
-go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
+go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg=
+go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E=
+go.opentelemetry.io/otel/metric v1.36.0 h1:MoWPKVhQvJ+eeXWHFBOPoBOi20jh6Iq2CcCREuTYufE=
+go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs=
+go.opentelemetry.io/otel/sdk v1.36.0 h1:b6SYIuLRs88ztox4EyrvRti80uXIFy+Sqzoh9kFULbs=
+go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY=
+go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis=
+go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4=
+go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w=
+go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
 go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
 go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
 go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
+go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
+go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
+go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
 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=
@@ -175,8 +191,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw=
 golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA=
-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/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
+golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
 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=
@@ -209,10 +225,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU=
 golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463 h1:e0AIkUUhxyBKh6ssZNrAMeqhA7RKUj42346d1y02i2g=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
-google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok=
-google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc=
+gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
+gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a h1:v2PbRU4K3llS09c7zodFpNePeamkAwG3mPrAery9VeE=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
+google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 h1:F29+wU6Ee6qgu9TddPgooOdaqsxTMunOoj8KA5yuS5A=
 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1/go.mod h1:5KF+wpkbTSbGcR9zteSqZV6fqFOWBl4Yde8En8MryZA=
 google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
@@ -232,16 +250,16 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-k8s.io/api v0.33.2 h1:YgwIS5jKfA+BZg//OQhkJNIfie/kmRsO0BmNaVSimvY=
-k8s.io/api v0.33.2/go.mod h1:fhrbphQJSM2cXzCWgqU29xLDuks4mu7ti9vveEnpSXs=
-k8s.io/apiextensions-apiserver v0.33.2 h1:6gnkIbngnaUflR3XwE1mCefN3YS8yTD631JXQhsU6M8=
-k8s.io/apiextensions-apiserver v0.33.2/go.mod h1:IvVanieYsEHJImTKXGP6XCOjTwv2LUMos0YWc9O+QP8=
-k8s.io/apimachinery v0.33.2 h1:IHFVhqg59mb8PJWTLi8m1mAoepkUNYmptHsV+Z1m5jY=
-k8s.io/apimachinery v0.33.2/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
-k8s.io/client-go v0.33.2 h1:z8CIcc0P581x/J1ZYf4CNzRKxRvQAwoAolYPbtQes+E=
-k8s.io/client-go v0.33.2/go.mod h1:9mCgT4wROvL948w6f6ArJNb7yQd7QsvqavDeZHvNmHo=
-k8s.io/code-generator v0.33.2 h1:PCJ0Y6viTCxxJHMOyGqYwWEteM4q6y1Hqo2rNpl6jF4=
-k8s.io/code-generator v0.33.2/go.mod h1:hBjCA9kPMpjLWwxcr75ReaQfFXY8u+9bEJJ7kRw3J8c=
+k8s.io/api v0.33.3 h1:SRd5t//hhkI1buzxb288fy2xvjubstenEKL9K51KBI8=
+k8s.io/api v0.33.3/go.mod h1:01Y/iLUjNBM3TAvypct7DIj0M0NIZc+PzAHCIo0CYGE=
+k8s.io/apiextensions-apiserver v0.33.3 h1:qmOcAHN6DjfD0v9kxL5udB27SRP6SG/MTopmge3MwEs=
+k8s.io/apiextensions-apiserver v0.33.3/go.mod h1:oROuctgo27mUsyp9+Obahos6CWcMISSAPzQ77CAQGz8=
+k8s.io/apimachinery v0.33.3 h1:4ZSrmNa0c/ZpZJhAgRdcsFcZOw1PQU1bALVQ0B3I5LA=
+k8s.io/apimachinery v0.33.3/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM=
+k8s.io/client-go v0.33.3 h1:M5AfDnKfYmVJif92ngN532gFqakcGi6RvaOF16efrpA=
+k8s.io/client-go v0.33.3/go.mod h1:luqKBQggEf3shbxHY4uVENAxrDISLOarxpTKMiUuujg=
+k8s.io/code-generator v0.33.3 h1:6+34LhYkIuQ/yn/E3qlpVqjQaP8smzCu4NE1A8b0LWs=
+k8s.io/code-generator v0.33.3/go.mod h1:6Y02+HQJYgNphv9z3wJB5w+sjYDIEBQW7sh62PkufvA=
 k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 h1:2OX19X59HxDprNCVrWi6jb7LW1PoqTlYqEq5H2oetog=
 k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU=
 k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
@@ -261,5 +279,6 @@ sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
 sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
 sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI=
 sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps=
-sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
 sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
+sigs.k8s.io/yaml v1.5.0 h1:M10b2U7aEUY6hRtU870n2VTPgR5RZiL/I6Lcc2F4NUQ=
+sigs.k8s.io/yaml v1.5.0/go.mod h1:wZs27Rbxoai4C0f8/9urLZtZtF3avA3gKvGyPdDqTO4=
diff --git a/hack/mkdocs/image/requirements.txt b/hack/mkdocs/image/requirements.txt
index a075a431..7a5fc4ad 100644
--- a/hack/mkdocs/image/requirements.txt
+++ b/hack/mkdocs/image/requirements.txt
@@ -10,7 +10,7 @@ MarkupSafe==3.0.2
 mkdocs==1.6.1
 mkdocs-awesome-pages-plugin==2.10.1
 mkdocs-macros-plugin==1.3.7
-mkdocs-material==9.6.15
+mkdocs-material==9.6.16
 mkdocs-redirects==1.2.2
 mkdocs-mermaid2-plugin==1.2.1
 pandas>=2.0.3
diff --git a/hack/test-crds-validation.sh b/hack/test-crds-validation.sh
deleted file mode 100755
index 8f3da81d..00000000
--- a/hack/test-crds-validation.sh
+++ /dev/null
@@ -1,152 +0,0 @@
-#!/bin/bash
-
-# Copyright 2020 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.
-
-set -o nounset
-set -o pipefail
-
-readonly GO111MODULE="on"
-readonly GOFLAGS="-mod=readonly"
-readonly GOPATH="$(mktemp -d)"
-readonly CLUSTER_NAME="verify-gateway-api"
-
-export KUBECONFIG="${GOPATH}/.kubeconfig"
-export GOFLAGS GO111MODULE GOPATH
-export PATH="${GOPATH}/bin:${PATH}"
-
-# Cleanup logic for cleanup on exit
-CLEANED_UP=false
-cleanup() {
-  if [ "$CLEANED_UP" = "true" ]; then
-    return
-  fi
-
-  if [ "${KIND_CREATE_ATTEMPTED:-}" = true ]; then
-    kind delete cluster --name "${CLUSTER_NAME}" || true
-  fi
-  CLEANED_UP=true
-}
-
-trap cleanup INT TERM EXIT
-
-# TODO(mlavacca): find a good way to keep this dependency up to date.
-KIND_VERSION="v0.26.0"
-
-# list of kind images taken from https://github.com/kubernetes-sigs/kind/releases/tag/v0.26.0.
-# they need to be updated when kind is updated.
-KIND_IMAGES=(
-  "kindest/node:v1.28.15@sha256:a7c05c7ae043a0b8c818f5a06188bc2c4098f6cb59ca7d1856df00375d839251"
-  "kindest/node:v1.29.12@sha256:62c0672ba99a4afd7396512848d6fc382906b8f33349ae68fb1dbfe549f70dec"
-  "kindest/node:v1.30.8@sha256:17cd608b3971338d9180b00776cb766c50d0a0b6b904ab4ff52fd3fc5c6369bf"
-  "kindest/node:v1.31.4@sha256:2cb39f7295fe7eafee0842b1052a599a4fb0f8bcf3f83d96c7f4864c357c6c30"
-  "kindest/node:v1.32.0@sha256:2458b423d635d7b01637cac2d6de7e1c1dca1148a2ba2e90975e214ca849e7cb"
-)
-
-if [ "$#" -gt 1 ]; then
-    echo "Error: Too many arguments provided. Only 1 argument is allowed."
-    exit 1
-fi
-
-DEFAULT_INDEX=$((1))
-
-if [ "$#" -eq 1 ]; then
-  # Check if the argument is a valid number between 1 and 5
-  if ! [[ "$1" =~ ^[1-5] ]]; then
-      echo "Error: Argument is not a valid integer between 1 and 5."
-      exit 1
-  fi
-  INDEX=$(($1))
-else
-  INDEX=$((DEFAULT_INDEX))
-fi
-
-K8S_IMAGE=${KIND_IMAGES[$((INDEX-1))]}
-echo "Using Kubernetes image: ${K8S_IMAGE}"
-
-# For exit code
-res=0
-
-# Install kind
-(cd "${GOPATH}" && go install sigs.k8s.io/kind@${KIND_VERSION}) || res=$?
-
-# Create cluster
-KIND_CREATE_ATTEMPTED=true
-kind create cluster --name "${CLUSTER_NAME}" --image "${K8S_IMAGE}" || res=$?
-
-# Verify CEL validation
-for CHANNEL in experimental standard; do
-  # Install CRDs.
-  kubectl apply -f "config/crd/${CHANNEL}/gateway*.yaml"
-
-  # Run tests.
-  go test -v -timeout=120s -count=1 --tags ${CHANNEL} sigs.k8s.io/gateway-api/pkg/test/cel || res=$?
-
-  # Delete CRDs to reset environment.
-  kubectl delete -f "config/crd/${CHANNEL}/gateway*.yaml"
-done
-
-# Temporary workaround for https://github.com/kubernetes/kubernetes/issues/104090
-sleep 8
-
-## Validate example YAMLs for each channel
-
-for CHANNEL in experimental standard; do
-  ##### Test valid CRD apply and that invalid examples are invalid.
-  # Install CRDs
-  kubectl apply -f "config/crd/${CHANNEL}/gateway*.yaml" || res=$?
-
-  # Temporary workaround for https://github.com/kubernetes/kubernetes/issues/104090
-  sleep 8
-
-  kubectl apply --recursive -f examples/standard || res=$?
-
-  # Install all experimental example gateway-api resources when experimental mode is enabled
-  if [[ "${CHANNEL}" == "experimental" ]]; then
-    echo "Experimental mode enabled: deploying experimental examples"
-    kubectl apply --recursive -f examples/experimental || res=$?
-  fi
-
-  # Find all our invalid examples and check them one by one.
-  # This lets us check the output in a cleaner way than a grep pipeline.
-  for file in $(find hack/invalid-examples -name "*.yaml"); do
-    # Don't check alpha resources in Standard checks
-    if [[ "$file" =~ "experimental" && "$CHANNEL" == "standard" ]]; then
-      continue
-    fi
-
-    KUBECTL_OUTPUT=$(kubectl apply -f "$file" 2>&1)
-
-    if [[ \
-          ! ("$KUBECTL_OUTPUT" =~ "is invalid") && \
-          ! ("$KUBECTL_OUTPUT" =~ "missing required field") &&  \
-          ! ("$KUBECTL_OUTPUT" =~ "denied the request") && \
-          ! ("$KUBECTL_OUTPUT" =~ "Invalid value") \
-          ]]; then
-      res=2
-      cat<<EOF
-
-Error: Example $file in channel $CHANNEL failed in an unexpected way with CEL validation.
-$KUBECTL_OUTPUT
-EOF
-    else
-    echo "Example $file in channel $CHANNEL failed as expected with CEL validation."
-    fi
-
-  done
-  kubectl delete -f "config/crd/${CHANNEL}/gateway*.yaml" || res=$?
-done
-
-### We've trapped EXIT with cleanup(), so just exit with what we've got.
-exit $res
diff --git a/mkdocs.yml b/mkdocs.yml
index 7765e320..18393ce4 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -132,10 +132,10 @@ nav:
       - geps/gep-2648/index.md
       - geps/gep-3779/index.md
       - geps/gep-3792/index.md
-      - geps/gep-3793/index.md
     - Implementable:
       - geps/gep-91/index.md
       - geps/gep-3567/index.md
+      - geps/gep-3949/index.md
     - Experimental:
       - geps/gep-1619/index.md
       - geps/gep-1713/index.md
diff --git a/pkg/features/backendtlspolicy.go b/pkg/features/backendtlspolicy.go
index 8763b32d..95d50171 100644
--- a/pkg/features/backendtlspolicy.go
+++ b/pkg/features/backendtlspolicy.go
@@ -1,5 +1,5 @@
 /*
-Copyright 2024 The Kubernetes Authors.
+Copyright 2025 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.
diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go
index cc919c61..9885f104 100644
--- a/pkg/generated/openapi/zz_generated.openapi.go
+++ b/pkg/generated/openapi/zz_generated.openapi.go
@@ -2862,12 +2862,22 @@ func schema_sigsk8sio_gateway_api_apis_v1_AllowedRoutes(ref common.ReferenceCall
 				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"namespaces": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Namespaces indicates namespaces from which Routes may be attached to this Listener. This is restricted to the namespace of this Gateway by default.\n\nSupport: Core",
 							Ref:         ref("sigs.k8s.io/gateway-api/apis/v1.RouteNamespaces"),
 						},
 					},
 					"kinds": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Kinds specifies the groups and kinds of Routes that are allowed to bind to this Gateway Listener. When unspecified or empty, the kinds of Routes selected are determined using the Listener protocol.\n\nA RouteGroupKind MUST correspond to kinds of Routes that are compatible with the application protocol specified in the Listener's Protocol field. If an implementation does not support or recognize this resource type, it MUST set the \"ResolvedRefs\" condition to False for this Listener with the \"InvalidRouteKinds\" reason.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -3004,6 +3014,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_CommonRouteSpec(ref common.ReferenceCa
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parentRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects.  If this is the case, then parentRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n  be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n  each ParentRef that selects the same object must set the same set of\n  optional fields to different values. If one ParentRef sets a\n  combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n  same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n  object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n  referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference.\n\n<gateway:experimental:description> ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. </gateway:experimental:description>\n\n<gateway:standard:validation:XValidation:message=\"sectionName must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))\"> <gateway:standard:validation:XValidation:message=\"sectionName must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))\">",
 							Type:        []string{"array"},
@@ -3079,6 +3094,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_FrontendTLSValidation(ref common.Refer
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"caCertificateRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "CACertificateRefs contains one or more references to Kubernetes objects that contain TLS certificates of the Certificate Authorities that can be used as a trust anchor to validate the certificates presented by the client.\n\nA single CA certificate reference to a Kubernetes ConfigMap has \"Core\" support. Implementations MAY choose to support attaching multiple CA certificates to a Listener, but this behavior is implementation-specific.\n\nSupport: Core - A single reference to a Kubernetes ConfigMap with the CA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific (More than one reference, or other kinds of resources).\n\nReferences to a resource in a different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. If a ReferenceGrant does not allow this reference, the \"ResolvedRefs\" condition MUST be set to False for this listener with the \"RefNotPermitted\" reason.",
 							Type:        []string{"array"},
@@ -3093,6 +3113,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_FrontendTLSValidation(ref common.Refer
 						},
 					},
 				},
+				Required: []string{"caCertificateRefs"},
 			},
 		},
 		Dependencies: []string{
@@ -3151,6 +3172,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCBackendRef(ref common.ReferenceCal
 						},
 					},
 					"filters": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Filters defined at this level MUST be executed if and only if the request is being forwarded to the backend defined here.\n\nSupport: Implementation-specific (For broader support of filters, use the Filters field in GRPCRouteRule.)",
 							Type:        []string{"array"},
@@ -3286,6 +3312,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRoute(ref common.ReferenceCallback
 						},
 					},
 				},
+				Required: []string{"spec"},
 			},
 		},
 		Dependencies: []string{
@@ -3448,6 +3475,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteRule(ref common.ReferenceCall
 						},
 					},
 					"matches": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Matches define conditions used for matching the rule against incoming gRPC requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied.\n\nFor example, take the following matches configuration:\n\n``` matches: - method:\n    service: foo.bar\n  headers:\n    values:\n      version: 2\n- method:\n    service: foo.bar.v2\n```\n\nFor a request to match against this rule, it MUST satisfy EITHER of the two conditions:\n\n- service of foo.bar AND contains the header `version: 2` - service of foo.bar.v2\n\nSee the documentation for GRPCRouteMatch on how to specify multiple match conditions to be ANDed together.\n\nIf no matches are specified, the implementation MUST match every gRPC request.\n\nProxy or Load Balancer routing configuration generated from GRPCRoutes MUST prioritize rules based on the following criteria, continuing on ties. Merging MUST not be done between GRPCRoutes and HTTPRoutes. Precedence MUST be given to the rule with the largest number of:\n\n* Characters in a matching non-wildcard hostname. * Characters in a matching hostname. * Characters in a matching service. * Characters in a matching method. * Header matches.\n\nIf ties still exist across multiple Routes, matching precedence MUST be determined in order of the following criteria, continuing on ties:\n\n* The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by\n  \"{namespace}/{name}\".\n\nIf ties still exist within the Route that has been given precedence, matching precedence MUST be granted to the first matching rule meeting the above criteria.",
 							Type:        []string{"array"},
@@ -3462,6 +3494,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteRule(ref common.ReferenceCall
 						},
 					},
 					"filters": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Filters define the filters that are applied to requests that match this rule.\n\nThe effects of ordering of multiple behaviors are currently unspecified. This can change in the future based on feedback during the alpha stage.\n\nConformance-levels at this level are defined based on the type of filter:\n\n- ALL core filters MUST be supported by all implementations that support\n  GRPCRoute.\n- Implementers are encouraged to support extended filters. - Implementation-specific custom filters have no API guarantees across\n  implementations.\n\nSpecifying the same filter multiple times is not supported unless explicitly indicated in the filter.\n\nIf an implementation cannot support a combination of filters, it must clearly document that limitation. In cases where incompatible or unsupported filters are specified and cause the `Accepted` condition to be set to status `False`, implementations may use the `IncompatibleFilters` reason to specify this configuration error.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -3476,6 +3513,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteRule(ref common.ReferenceCall
 						},
 					},
 					"backendRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "BackendRefs defines the backend(s) where matching requests should be sent.\n\nFailure behavior here depends on how many BackendRefs are specified and how many are invalid.\n\nIf *all* entries in BackendRefs are invalid, and there are also no filters specified in this route rule, *all* traffic which matches this rule MUST receive an `UNAVAILABLE` status.\n\nSee the GRPCBackendRef definition for the rules about what makes a single GRPCBackendRef invalid.\n\nWhen a GRPCBackendRef is invalid, `UNAVAILABLE` statuses MUST be returned for requests that would have otherwise been routed to an invalid backend. If multiple backends are specified, and some are invalid, the proportion of requests that would otherwise have been routed to an invalid backend MUST receive an `UNAVAILABLE` status.\n\nFor example, if two backends are specified with equal weights, and one is invalid, 50 percent of traffic MUST receive an `UNAVAILABLE` status. Implementations may choose how that 50 percent is determined.\n\nSupport: Core for Kubernetes Service\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Core",
 							Type:        []string{"array"},
@@ -3511,6 +3553,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteSpec(ref common.ReferenceCall
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parentRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects.  If this is the case, then parentRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n  be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n  each ParentRef that selects the same object must set the same set of\n  optional fields to different values. If one ParentRef sets a\n  combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n  same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n  object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n  referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference.\n\n<gateway:experimental:description> ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. </gateway:experimental:description>\n\n<gateway:standard:validation:XValidation:message=\"sectionName must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))\"> <gateway:standard:validation:XValidation:message=\"sectionName must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))\">",
 							Type:        []string{"array"},
@@ -3525,6 +3572,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteSpec(ref common.ReferenceCall
 						},
 					},
 					"hostnames": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Hostnames defines a set of hostnames to match against the GRPC Host header to select a GRPCRoute to process the request. This matches the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n   label MUST appear by itself as the first label.\n\nIf a hostname is specified by both the Listener and GRPCRoute, there MUST be at least one intersecting hostname for the GRPCRoute to be attached to the Listener. For example:\n\n* A Listener with `test.example.com` as the hostname matches GRPCRoutes\n  that have either not specified any hostnames, or have specified at\n  least one of `test.example.com` or `*.example.com`.\n* A Listener with `*.example.com` as the hostname matches GRPCRoutes\n  that have either not specified any hostnames or have specified at least\n  one hostname that matches the Listener hostname. For example,\n  `test.example.com` and `*.example.com` would both match. On the other\n  hand, `example.com` and `test.example.net` would not match.\n\nHostnames that are prefixed with a wildcard label (`*.`) are interpreted as a suffix match. That means that a match for `*.example.com` would match both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\nIf both the Listener and GRPCRoute have specified hostnames, any GRPCRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the GRPCRoute specified `test.example.com` and `test.example.net`, `test.example.net` MUST NOT be considered for a match.\n\nIf both the Listener and GRPCRoute have specified hostnames, and none match with the criteria above, then the GRPCRoute MUST NOT be accepted by the implementation. The implementation MUST raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus.\n\nIf a Route (A) of type HTTPRoute or GRPCRoute is attached to a Listener and that listener already has another Route (B) of the other type attached and the intersection of the hostnames of A and B is non-empty, then the implementation MUST accept exactly one of these two routes, determined by the following criteria, in order:\n\n* The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by\n  \"{namespace}/{name}\".\n\nThe rejected Route MUST raise an 'Accepted' condition with a status of 'False' in the corresponding RouteParentStatus.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -3540,6 +3592,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteSpec(ref common.ReferenceCall
 						},
 					},
 					"rules": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Rules are a list of GRPC matchers, filters and actions.\n\n<gateway:experimental:validation:XValidation:message=\"Rule name must be unique within the route\",rule=\"self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))\">",
 							Type:        []string{"array"},
@@ -3569,6 +3626,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GRPCRouteStatus(ref common.ReferenceCa
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parents": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway.",
 							Type:        []string{"array"},
@@ -3996,6 +4058,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewaySpec(ref common.ReferenceCallba
 						},
 					},
 					"addresses": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Addresses requested for this Gateway. This is optional and behavior can depend on the implementation. If a value is set in the spec and the requested address is invalid or unavailable, the implementation MUST indicate this in the associated entry in GatewayStatus.Addresses.\n\nThe Addresses field represents a request for the address(es) on the \"outside of the Gateway\", that traffic bound for this Gateway will use. This could be the IP address or hostname of an external load balancer or other networking infrastructure, or some other address that traffic will be sent to.\n\nIf no Addresses are specified, the implementation MAY schedule the Gateway in an implementation-specific manner, assigning an appropriate set of Addresses.\n\nThe implementation MUST bind all Listeners to every GatewayAddress that it assigns to the Gateway and add a corresponding entry in GatewayStatus.Addresses.\n\nSupport: Extended\n\n<gateway:validateIPAddress>",
 							Type:        []string{"array"},
@@ -4071,6 +4138,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewayStatus(ref common.ReferenceCall
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"addresses": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Addresses lists the network addresses that have been bound to the Gateway.\n\nThis list may differ from the addresses provided in the spec under some conditions:\n\n  * no addresses are specified, all addresses are dynamically assigned\n  * a combination of specified and dynamic addresses are assigned\n  * a specified address was unusable (e.g. already in use)\n\n<gateway:validateIPAddress>",
 							Type:        []string{"array"},
@@ -4179,6 +4251,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_GatewayTLSConfig(ref common.ReferenceC
 						},
 					},
 					"certificateRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "CertificateRefs contains a series of references to Kubernetes objects that contains TLS certificates and private keys. These certificates are used to establish a TLS handshake for requests that match the hostname of the associated listener.\n\nA single CertificateRef to a Kubernetes Secret has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a Listener, but this behavior is implementation-specific.\n\nReferences to a resource in different namespace are invalid UNLESS there is a ReferenceGrant in the target namespace that allows the certificate to be attached. If a ReferenceGrant does not allow this reference, the \"ResolvedRefs\" condition MUST be set to False for this listener with the \"RefNotPermitted\" reason.\n\nThis field is required to have at least one element when the mode is set to \"Terminate\" (default) and is optional otherwise.\n\nCertificateRefs can reference to standard Kubernetes resources, i.e. Secret, or implementation-specific custom resources.\n\nSupport: Core - A single reference to a Kubernetes Secret of type kubernetes.io/tls\n\nSupport: Implementation-specific (More than one reference or other resource types)",
 							Type:        []string{"array"},
@@ -4273,6 +4350,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPBackendRef(ref common.ReferenceCal
 						},
 					},
 					"filters": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Filters defined at this level should be executed if and only if the request is being forwarded to the backend defined here.\n\nSupport: Implementation-specific (For broader support of filters, use the Filters field in HTTPRouteRule.)",
 							Type:        []string{"array"},
@@ -4978,6 +5060,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteRetry(ref common.ReferenceCal
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"codes": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Codes defines the HTTP response status codes for which a backend request should be retried.\n\nSupport: Extended",
 							Type:        []string{"array"},
@@ -5027,6 +5114,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteRule(ref common.ReferenceCall
 						},
 					},
 					"matches": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Matches define conditions used for matching the rule against incoming HTTP requests. Each match is independent, i.e. this rule will be matched if **any** one of the matches is satisfied.\n\nFor example, take the following matches configuration:\n\n``` matches: - path:\n    value: \"/foo\"\n  headers:\n  - name: \"version\"\n    value: \"v2\"\n- path:\n    value: \"/v2/foo\"\n```\n\nFor a request to match against this rule, a request must satisfy EITHER of the two conditions:\n\n- path prefixed with `/foo` AND contains the header `version: v2` - path prefix of `/v2/foo`\n\nSee the documentation for HTTPRouteMatch on how to specify multiple match conditions that should be ANDed together.\n\nIf no matches are specified, the default is a prefix path match on \"/\", which has the effect of matching every HTTP request.\n\nProxy or Load Balancer routing configuration generated from HTTPRoutes MUST prioritize matches based on the following criteria, continuing on ties. Across all rules specified on applicable Routes, precedence must be given to the match having:\n\n* \"Exact\" path match. * \"Prefix\" path match with largest number of characters. * Method match. * Largest number of header matches. * Largest number of query param matches.\n\nNote: The precedence of RegularExpression path matches are implementation-specific.\n\nIf ties still exist across multiple Routes, matching precedence MUST be determined in order of the following criteria, continuing on ties:\n\n* The oldest Route based on creation timestamp. * The Route appearing first in alphabetical order by\n  \"{namespace}/{name}\".\n\nIf ties still exist within an HTTPRoute, matching precedence MUST be granted to the FIRST matching rule (in list order) with a match meeting the above criteria.\n\nWhen no rules matching a request have been successfully attached to the parent a request is coming from, a HTTP 404 status code MUST be returned.",
 							Type:        []string{"array"},
@@ -5041,6 +5133,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteRule(ref common.ReferenceCall
 						},
 					},
 					"filters": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Filters define the filters that are applied to requests that match this rule.\n\nWherever possible, implementations SHOULD implement filters in the order they are specified.\n\nImplementations MAY choose to implement this ordering strictly, rejecting any combination or order of filters that cannot be supported. If implementations choose a strict interpretation of filter ordering, they MUST clearly document that behavior.\n\nTo reject an invalid combination or order of filters, implementations SHOULD consider the Route Rules with this configuration invalid. If all Route Rules in a Route are invalid, the entire Route would be considered invalid. If only a portion of Route Rules are invalid, implementations MUST set the \"PartiallyInvalid\" condition for the Route.\n\nConformance-levels at this level are defined based on the type of filter:\n\n- ALL core filters MUST be supported by all implementations. - Implementers are encouraged to support extended filters. - Implementation-specific custom filters have no API guarantees across\n  implementations.\n\nSpecifying the same filter multiple times is not supported unless explicitly indicated in the filter.\n\nAll filters are expected to be compatible with each other except for the URLRewrite and RequestRedirect filters, which may not be combined. If an implementation cannot support other combinations of filters, they must clearly document that limitation. In cases where incompatible or unsupported filters are specified and cause the `Accepted` condition to be set to status `False`, implementations may use the `IncompatibleFilters` reason to specify this configuration error.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -5055,6 +5152,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteRule(ref common.ReferenceCall
 						},
 					},
 					"backendRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "BackendRefs defines the backend(s) where matching requests should be sent.\n\nFailure behavior here depends on how many BackendRefs are specified and how many are invalid.\n\nIf *all* entries in BackendRefs are invalid, and there are also no filters specified in this route rule, *all* traffic which matches this rule MUST receive a 500 status code.\n\nSee the HTTPBackendRef definition for the rules about what makes a single HTTPBackendRef invalid.\n\nWhen a HTTPBackendRef is invalid, 500 status codes MUST be returned for requests that would have otherwise been routed to an invalid backend. If multiple backends are specified, and some are invalid, the proportion of requests that would otherwise have been routed to an invalid backend MUST receive a 500 status code.\n\nFor example, if two backends are specified with equal weights, and one is invalid, 50 percent of traffic must receive a 500. Implementations may choose how that 50 percent is determined.\n\nWhen a HTTPBackendRef refers to a Service that has no ready endpoints, implementations SHOULD return a 503 for requests to that backend instead. If an implementation chooses to do this, all of the above rules for 500 responses MUST also apply for responses that return a 503.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Core",
 							Type:        []string{"array"},
@@ -5102,6 +5204,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteSpec(ref common.ReferenceCall
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parentRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects.  If this is the case, then parentRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n  be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n  each ParentRef that selects the same object must set the same set of\n  optional fields to different values. If one ParentRef sets a\n  combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n  same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n  object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n  referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference.\n\n<gateway:experimental:description> ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. </gateway:experimental:description>\n\n<gateway:standard:validation:XValidation:message=\"sectionName must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))\"> <gateway:standard:validation:XValidation:message=\"sectionName must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))\">",
 							Type:        []string{"array"},
@@ -5116,6 +5223,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteSpec(ref common.ReferenceCall
 						},
 					},
 					"hostnames": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Hostnames defines a set of hostnames that should match against the HTTP Host header to select a HTTPRoute used to process the request. Implementations MUST ignore any port value specified in the HTTP Host header while performing a match and (absent of any applicable header modification configuration) MUST forward this header unmodified to the backend.\n\nValid values for Hostnames are determined by RFC 1123 definition of a hostname with 2 notable exceptions:\n\n1. IPs are not allowed. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n   label must appear by itself as the first label.\n\nIf a hostname is specified by both the Listener and HTTPRoute, there must be at least one intersecting hostname for the HTTPRoute to be attached to the Listener. For example:\n\n* A Listener with `test.example.com` as the hostname matches HTTPRoutes\n  that have either not specified any hostnames, or have specified at\n  least one of `test.example.com` or `*.example.com`.\n* A Listener with `*.example.com` as the hostname matches HTTPRoutes\n  that have either not specified any hostnames or have specified at least\n  one hostname that matches the Listener hostname. For example,\n  `*.example.com`, `test.example.com`, and `foo.test.example.com` would\n  all match. On the other hand, `example.com` and `test.example.net` would\n  not match.\n\nHostnames that are prefixed with a wildcard label (`*.`) are interpreted as a suffix match. That means that a match for `*.example.com` would match both `test.example.com`, and `foo.test.example.com`, but not `example.com`.\n\nIf both the Listener and HTTPRoute have specified hostnames, any HTTPRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the HTTPRoute specified `test.example.com` and `test.example.net`, `test.example.net` must not be considered for a match.\n\nIf both the Listener and HTTPRoute have specified hostnames, and none match with the criteria above, then the HTTPRoute is not accepted. The implementation must raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus.\n\nIn the event that multiple HTTPRoutes specify intersecting hostnames (e.g. overlapping wildcard matching and exact matching hostnames), precedence must be given to rules from the HTTPRoute with the largest number of:\n\n* Characters in a matching non-wildcard hostname. * Characters in a matching hostname.\n\nIf ties exist across multiple Routes, the matching precedence rules for HTTPRouteMatches takes over.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -5131,6 +5243,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteSpec(ref common.ReferenceCall
 						},
 					},
 					"rules": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Rules are a list of HTTP matchers, filters and actions.\n\n<gateway:experimental:validation:XValidation:message=\"Rule name must be unique within the route\",rule=\"self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))\">",
 							Type:        []string{"array"},
@@ -5160,6 +5277,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_HTTPRouteStatus(ref common.ReferenceCa
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parents": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway.",
 							Type:        []string{"array"},
@@ -5340,6 +5462,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_ListenerStatus(ref common.ReferenceCal
 						},
 					},
 					"supportedKinds": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "SupportedKinds is the list indicating the Kinds supported by this listener. This MUST represent the kinds an implementation supports for that Listener configuration.\n\nIf kinds are specified in Spec that are not supported, they MUST NOT appear in this list and an implementation MUST set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid and invalid Route kinds are specified, the implementation MUST reference the valid Route kinds that have been specified.",
 							Type:        []string{"array"},
@@ -5716,7 +5843,7 @@ func schema_sigsk8sio_gateway_api_apis_v1_RouteParentStatus(ref common.Reference
 						},
 					},
 				},
-				Required: []string{"parentRef", "controllerName"},
+				Required: []string{"parentRef", "controllerName", "conditions"},
 			},
 		},
 		Dependencies: []string{
@@ -5732,6 +5859,11 @@ func schema_sigsk8sio_gateway_api_apis_v1_RouteStatus(ref common.ReferenceCallba
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parents": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway.",
 							Type:        []string{"array"},
@@ -5927,6 +6059,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_GRPCRoute(ref common.ReferenceCa
 						},
 					},
 				},
+				Required: []string{"spec"},
 			},
 		},
 		Dependencies: []string{
@@ -6154,7 +6287,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_PolicyAncestorStatus(ref common.
 						},
 					},
 				},
-				Required: []string{"ancestorRef", "controllerName"},
+				Required: []string{"ancestorRef", "controllerName", "conditions"},
 			},
 		},
 		Dependencies: []string{
@@ -6169,6 +6302,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_PolicyStatus(ref common.Referenc
 				Type: []string{"object"},
 				Properties: map[string]spec.Schema{
 					"ancestors": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Ancestors is a list of ancestor resources (usually Gateways) that are associated with the policy, and the status of the policy with respect to each ancestor. When this policy attaches to a parent, the controller that manages the parent and the ancestors MUST add an entry to this list when the controller first sees the policy and SHOULD update the entry as appropriate when the relevant ancestor is modified.\n\nNote that choosing the relevant ancestor is left to the Policy designers; an important part of Policy design is designing the right object level at which to namespace this status.\n\nNote also that implementations MUST ONLY populate ancestor status for the Ancestor resources they are responsible for. Implementations MUST use the ControllerName field to uniquely identify the entries in this list that they are responsible for.\n\nNote that to achieve this, the list of PolicyAncestorStatus structs MUST be treated as a map with a composite key, made up of the AncestorRef and ControllerName fields combined.\n\nA maximum of 16 ancestors will be represented in this list. An empty list means the Policy is not relevant for any ancestors.\n\nIf this slice is full, implementations MUST NOT add further entries. Instead they MUST consider the policy unimplementable and signal that on any related resources such as the ancestor that would be referenced here. For example, if this list was full on BackendTLSPolicy, no additional Gateways would be able to reference the Service targeted by the BackendTLSPolicy.",
 							Type:        []string{"array"},
@@ -6396,6 +6534,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TCPRouteRule(ref common.Referenc
 						},
 					},
 					"backendRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a nonexistent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Connection rejections must respect weight; if an invalid backend is requested to have 80% of connections, then 80% of connections must be rejected instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended",
 							Type:        []string{"array"},
@@ -6410,6 +6553,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TCPRouteRule(ref common.Referenc
 						},
 					},
 				},
+				Required: []string{"backendRefs"},
 			},
 		},
 		Dependencies: []string{
@@ -6425,6 +6569,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TCPRouteSpec(ref common.Referenc
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parentRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects.  If this is the case, then parentRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n  be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n  each ParentRef that selects the same object must set the same set of\n  optional fields to different values. If one ParentRef sets a\n  combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n  same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n  object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n  referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference.\n\n<gateway:experimental:description> ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. </gateway:experimental:description>\n\n<gateway:standard:validation:XValidation:message=\"sectionName must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))\"> <gateway:standard:validation:XValidation:message=\"sectionName must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))\">",
 							Type:        []string{"array"},
@@ -6439,6 +6588,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TCPRouteSpec(ref common.Referenc
 						},
 					},
 					"rules": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Rules are a list of TCP matchers and actions.\n\n<gateway:experimental:validation:XValidation:message=\"Rule name must be unique within the route\",rule=\"self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))\">",
 							Type:        []string{"array"},
@@ -6469,6 +6623,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TCPRouteStatus(ref common.Refere
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parents": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway.",
 							Type:        []string{"array"},
@@ -6605,6 +6764,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TLSRouteRule(ref common.Referenc
 						},
 					},
 					"backendRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a nonexistent resource or a Service with no endpoints), the rule performs no forwarding; if no filters are specified that would result in a response being sent, the underlying implementation must actively reject request attempts to this backend, by rejecting the connection or returning a 500 status code. Request rejections must respect weight; if an invalid backend is requested to have 80% of requests, then 80% of requests must be rejected instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended",
 							Type:        []string{"array"},
@@ -6619,6 +6783,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TLSRouteRule(ref common.Referenc
 						},
 					},
 				},
+				Required: []string{"backendRefs"},
 			},
 		},
 		Dependencies: []string{
@@ -6634,6 +6799,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TLSRouteSpec(ref common.Referenc
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parentRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects.  If this is the case, then parentRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n  be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n  each ParentRef that selects the same object must set the same set of\n  optional fields to different values. If one ParentRef sets a\n  combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n  same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n  object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n  referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference.\n\n<gateway:experimental:description> ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. </gateway:experimental:description>\n\n<gateway:standard:validation:XValidation:message=\"sectionName must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))\"> <gateway:standard:validation:XValidation:message=\"sectionName must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))\">",
 							Type:        []string{"array"},
@@ -6648,6 +6818,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TLSRouteSpec(ref common.Referenc
 						},
 					},
 					"hostnames": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Hostnames defines a set of SNI names that should match against the SNI attribute of TLS ClientHello message in TLS handshake. This matches the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n1. IPs are not allowed in SNI names per RFC 6066. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n   label must appear by itself as the first label.\n\nIf a hostname is specified by both the Listener and TLSRoute, there must be at least one intersecting hostname for the TLSRoute to be attached to the Listener. For example:\n\n* A Listener with `test.example.com` as the hostname matches TLSRoutes\n  that have either not specified any hostnames, or have specified at\n  least one of `test.example.com` or `*.example.com`.\n* A Listener with `*.example.com` as the hostname matches TLSRoutes\n  that have either not specified any hostnames or have specified at least\n  one hostname that matches the Listener hostname. For example,\n  `test.example.com` and `*.example.com` would both match. On the other\n  hand, `example.com` and `test.example.net` would not match.\n\nIf both the Listener and TLSRoute have specified hostnames, any TLSRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the TLSRoute specified `test.example.com` and `test.example.net`, `test.example.net` must not be considered for a match.\n\nIf both the Listener and TLSRoute have specified hostnames, and none match with the criteria above, then the TLSRoute is not accepted. The implementation must raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -6663,6 +6838,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TLSRouteSpec(ref common.Referenc
 						},
 					},
 					"rules": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Rules are a list of TLS matchers and actions.\n\n<gateway:experimental:validation:XValidation:message=\"Rule name must be unique within the route\",rule=\"self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))\">",
 							Type:        []string{"array"},
@@ -6693,6 +6873,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_TLSRouteStatus(ref common.Refere
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parents": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway.",
 							Type:        []string{"array"},
@@ -6829,6 +7014,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_UDPRouteRule(ref common.Referenc
 						},
 					},
 					"backendRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "BackendRefs defines the backend(s) where matching requests should be sent. If unspecified or invalid (refers to a nonexistent resource or a Service with no endpoints), the underlying implementation MUST actively reject connection attempts to this backend. Packet drops must respect weight; if an invalid backend is requested to have 80% of the packets, then 80% of packets must be dropped instead.\n\nSupport: Core for Kubernetes Service\n\nSupport: Extended for Kubernetes ServiceImport\n\nSupport: Implementation-specific for any other resource\n\nSupport for weight: Extended",
 							Type:        []string{"array"},
@@ -6843,6 +7033,7 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_UDPRouteRule(ref common.Referenc
 						},
 					},
 				},
+				Required: []string{"backendRefs"},
 			},
 		},
 		Dependencies: []string{
@@ -6858,6 +7049,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_UDPRouteSpec(ref common.Referenc
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parentRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects.  If this is the case, then parentRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n  be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n  each ParentRef that selects the same object must set the same set of\n  optional fields to different values. If one ParentRef sets a\n  combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n  same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n  object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n  referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference.\n\n<gateway:experimental:description> ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. </gateway:experimental:description>\n\n<gateway:standard:validation:XValidation:message=\"sectionName must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))\"> <gateway:standard:validation:XValidation:message=\"sectionName must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))\">",
 							Type:        []string{"array"},
@@ -6872,6 +7068,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_UDPRouteSpec(ref common.Referenc
 						},
 					},
 					"rules": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Rules are a list of UDP matchers and actions.\n\n<gateway:experimental:validation:XValidation:message=\"Rule name must be unique within the route\",rule=\"self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))\">",
 							Type:        []string{"array"},
@@ -6902,6 +7103,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha2_UDPRouteStatus(ref common.Refere
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parents": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Parents is a list of parent resources (usually Gateways) that are associated with the route, and the status of the route with respect to each parent. When this route attaches to a parent, the controller that manages the parent must add an entry to this list when the controller first sees the route and should update the entry as appropriate when the route or gateway is modified.\n\nNote that parent references that cannot be resolved by an implementation of this API will not be added to this list. Implementations of this API can only populate Route status for the Gateways/parent resources they are responsible for.\n\nA maximum of 32 Gateways will be represented in this list. An empty list means the route has not been attached to any Gateway.",
 							Type:        []string{"array"},
@@ -7031,6 +7237,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicySpec(ref common.
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"targetRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "TargetRefs identifies an API object to apply the policy to. Only Services have Extended support. Implementations MAY support additional objects, with Implementation Specific support. Note that this config applies to the entire referenced resource by default, but this default may change in the future to provide a more granular application of the policy.\n\nTargetRefs must be _distinct_. This means either that:\n\n* They select different targets. If this is the case, then targetRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, and `name` must\n  be unique across all targetRef entries in the BackendTLSPolicy.\n* They select different sectionNames in the same target.\n\nSupport: Extended for Kubernetes Service\n\nSupport: Implementation-specific for any other resource",
 							Type:        []string{"array"},
@@ -7084,6 +7295,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicyValidation(ref c
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"caCertificateRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "CACertificateRefs contains one or more references to Kubernetes objects that contain a PEM-encoded TLS CA certificate bundle, which is used to validate a TLS handshake between the Gateway and backend Pod.\n\nIf CACertificateRefs is empty or unspecified, then WellKnownCACertificates must be specified. Only one of CACertificateRefs or WellKnownCACertificates may be specified, not both. If CACertificateRefs is empty or unspecified, the configuration for WellKnownCACertificates MUST be honored instead if supported by the implementation.\n\nReferences to a resource in a different namespace are invalid for the moment, although we will revisit this in the future.\n\nA single CACertificateRef to a Kubernetes ConfigMap kind has \"Core\" support. Implementations MAY choose to support attaching multiple certificates to a backend, but this behavior is implementation-specific.\n\nSupport: Core - An optional single reference to a Kubernetes ConfigMap, with the CA certificate in a key named `ca.crt`.\n\nSupport: Implementation-specific (More than one reference, or other kinds of resources).",
 							Type:        []string{"array"},
@@ -7098,6 +7314,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicyValidation(ref c
 						},
 					},
 					"wellKnownCACertificates": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "WellKnownCACertificates specifies whether system CA certificates may be used in the TLS handshake between the gateway and backend pod.\n\nIf WellKnownCACertificates is unspecified or empty (\"\"), then CACertificateRefs must be specified with at least one entry for a valid configuration. Only one of CACertificateRefs or WellKnownCACertificates may be specified, not both. If an implementation does not support the WellKnownCACertificates field or the value supplied is not supported, the Status Conditions on the Policy MUST be updated to include an Accepted: False Condition with Reason: Invalid.\n\nSupport: Implementation-specific",
 							Type:        []string{"string"},
@@ -7113,6 +7334,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_BackendTLSPolicyValidation(ref c
 						},
 					},
 					"subjectAltNames": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "SubjectAltNames contains one or more Subject Alternative Names. When specified the certificate served from the backend MUST have at least one Subject Alternate Name matching one of the specified SubjectAltNames.\n\nSupport: Extended",
 							Type:        []string{"array"},
@@ -7278,6 +7504,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_TLSRouteSpec(ref common.Referenc
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"parentRefs": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "ParentRefs references the resources (usually Gateways) that a Route wants to be attached to. Note that the referenced parent resource needs to allow this for the attachment to be complete. For Gateways, that means the Gateway needs to allow attachment from Routes of this kind and namespace. For Services, that means the Service must either be in the same namespace for a \"producer\" route, or the mesh implementation must support and allow \"consumer\" routes for the referenced Service. ReferenceGrant is not applicable for governing ParentRefs to Services - it is not possible to create a \"producer\" route for a Service in a different namespace from the Route.\n\nThere are two kinds of parent resources with \"Core\" support:\n\n* Gateway (Gateway conformance profile) * Service (Mesh conformance profile, ClusterIP Services only)\n\nThis API may be extended in the future to support additional kinds of parent resources.\n\nParentRefs must be _distinct_. This means either that:\n\n* They select different objects.  If this is the case, then parentRef\n  entries are distinct. In terms of fields, this means that the\n  multi-part key defined by `group`, `kind`, `namespace`, and `name` must\n  be unique across all parentRef entries in the Route.\n* They do not select different objects, but for each optional field used,\n  each ParentRef that selects the same object must set the same set of\n  optional fields to different values. If one ParentRef sets a\n  combination of optional fields, all must set the same combination.\n\nSome examples:\n\n* If one ParentRef sets `sectionName`, all ParentRefs referencing the\n  same object must also set `sectionName`.\n* If one ParentRef sets `port`, all ParentRefs referencing the same\n  object must also set `port`.\n* If one ParentRef sets `sectionName` and `port`, all ParentRefs\n  referencing the same object must also set `sectionName` and `port`.\n\nIt is possible to separately reference multiple distinct objects that may be collapsed by an implementation. For example, some implementations may choose to merge compatible Gateway Listeners together. If that is the case, the list of routes attached to those resources should also be merged.\n\nNote that for ParentRefs that cross namespace boundaries, there are specific rules. Cross-namespace references are only valid if they are explicitly allowed by something in the namespace they are referring to. For example, Gateway has the AllowedRoutes field, and ReferenceGrant provides a generic way to enable other kinds of cross-namespace reference.\n\n<gateway:experimental:description> ParentRefs from a Route to a Service in the same namespace are \"producer\" routes, which apply default routing rules to inbound connections from any namespace to the Service.\n\nParentRefs from a Route to a Service in a different namespace are \"consumer\" routes, and these routing rules are only applied to outbound connections originating from the same namespace as the Route, for which the intended destination of the connections are a Service targeted as a ParentRef of the Route. </gateway:experimental:description>\n\n<gateway:standard:validation:XValidation:message=\"sectionName must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '')) : true))\"> <gateway:standard:validation:XValidation:message=\"sectionName must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || (has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName))))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be specified when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.all(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__)) ? ((!has(p1.sectionName) || p1.sectionName == '') == (!has(p2.sectionName) || p2.sectionName == '') && (!has(p1.port) || p1.port == 0) == (!has(p2.port) || p2.port == 0)): true))\"> <gateway:experimental:validation:XValidation:message=\"sectionName or port must be unique when parentRefs includes 2 or more references to the same parent\",rule=\"self.all(p1, self.exists_one(p2, p1.group == p2.group && p1.kind == p2.kind && p1.name == p2.name && (((!has(p1.__namespace__) || p1.__namespace__ == '') && (!has(p2.__namespace__) || p2.__namespace__ == '')) || (has(p1.__namespace__) && has(p2.__namespace__) && p1.__namespace__ == p2.__namespace__ )) && (((!has(p1.sectionName) || p1.sectionName == '') && (!has(p2.sectionName) || p2.sectionName == '')) || ( has(p1.sectionName) && has(p2.sectionName) && p1.sectionName == p2.sectionName)) && (((!has(p1.port) || p1.port == 0) && (!has(p2.port) || p2.port == 0)) || (has(p1.port) && has(p2.port) && p1.port == p2.port))))\">",
 							Type:        []string{"array"},
@@ -7292,6 +7523,11 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_TLSRouteSpec(ref common.Referenc
 						},
 					},
 					"hostnames": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "Hostnames defines a set of SNI hostnames that should match against the SNI attribute of TLS ClientHello message in TLS handshake. This matches the RFC 1123 definition of a hostname with 2 notable exceptions:\n\n1. IPs are not allowed in SNI hostnames per RFC 6066. 2. A hostname may be prefixed with a wildcard label (`*.`). The wildcard\n   label must appear by itself as the first label.\n\nIf a hostname is specified by both the Listener and TLSRoute, there must be at least one intersecting hostname for the TLSRoute to be attached to the Listener. For example:\n\n* A Listener with `test.example.com` as the hostname matches TLSRoutes\n  that have specified at least one of `test.example.com` or\n  `*.example.com`.\n* A Listener with `*.example.com` as the hostname matches TLSRoutes\n  that have specified at least one hostname that matches the Listener\n  hostname. For example, `test.example.com` and `*.example.com` would both\n  match. On the other hand, `example.com` and `test.example.net` would not\n  match.\n\nIf both the Listener and TLSRoute have specified hostnames, any TLSRoute hostnames that do not match the Listener hostname MUST be ignored. For example, if a Listener specified `*.example.com`, and the TLSRoute specified `test.example.com` and `test.example.net`, `test.example.net` must not be considered for a match.\n\nIf both the Listener and TLSRoute have specified hostnames, and none match with the criteria above, then the TLSRoute is not accepted. The implementation must raise an 'Accepted' Condition with a status of `False` in the corresponding RouteParentStatus.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -7307,8 +7543,13 @@ func schema_sigsk8sio_gateway_api_apis_v1alpha3_TLSRouteSpec(ref common.Referenc
 						},
 					},
 					"rules": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
-							Description: "Rules are a list of TLS matchers and actions.\n\n<gateway:experimental:validation:XValidation:message=\"Rule name must be unique within the route\",rule=\"self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))\">",
+							Description: "Rules are a list of actions.\n\n<gateway:experimental:validation:XValidation:message=\"Rule name must be unique within the route\",rule=\"self.all(l1, !has(l1.name) || self.exists_one(l2, has(l2.name) && l1.name == l2.name))\">",
 							Type:        []string{"array"},
 							Items: &spec.SchemaOrArray{
 								Schema: &spec.Schema{
@@ -7763,6 +8004,11 @@ func schema_sigsk8sio_gateway_api_apis_v1beta1_ReferenceGrantSpec(ref common.Ref
 				Type:        []string{"object"},
 				Properties: map[string]spec.Schema{
 					"from": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "From describes the trusted namespaces and kinds that can reference the resources described in \"To\". Each entry in this list MUST be considered to be an additional place that references can be valid from, or to put this another way, entries MUST be combined using OR.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -7777,6 +8023,11 @@ func schema_sigsk8sio_gateway_api_apis_v1beta1_ReferenceGrantSpec(ref common.Ref
 						},
 					},
 					"to": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "To describes the resources that may be referenced by the resources described in \"From\". Each entry in this list MUST be considered to be an additional place that references can be valid to, or to put this another way, entries MUST be combined using OR.\n\nSupport: Core",
 							Type:        []string{"array"},
@@ -7938,8 +8189,7 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_ListenerEntry(ref common.Refere
 					},
 					"port": {
 						SchemaProps: spec.SchemaProps{
-							Description: "Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules.",
-							Default:     0,
+							Description: "Port is the network port. Multiple listeners may use the same port, subject to the Listener compatibility rules.\n\nIf the port is not set or specified as zero, the implementation will assign a unique port. If the implementation does not support dynamic port assignment, it MUST set `Accepted` condition to `False` with the `UnsupportedPort` reason.",
 							Type:        []string{"integer"},
 							Format:      "int32",
 						},
@@ -7965,7 +8215,7 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_ListenerEntry(ref common.Refere
 						},
 					},
 				},
-				Required: []string{"name", "port", "protocol"},
+				Required: []string{"name", "protocol"},
 			},
 		},
 		Dependencies: []string{
@@ -7997,6 +8247,11 @@ func schema_sigsk8sio_gateway_api_apisx_v1alpha1_ListenerEntryStatus(ref common.
 						},
 					},
 					"supportedKinds": {
+						VendorExtensible: spec.VendorExtensible{
+							Extensions: spec.Extensions{
+								"x-kubernetes-list-type": "atomic",
+							},
+						},
 						SchemaProps: spec.SchemaProps{
 							Description: "SupportedKinds is the list indicating the Kinds supported by this listener. This MUST represent the kinds an implementation supports for that Listener configuration.\n\nIf kinds are specified in Spec that are not supported, they MUST NOT appear in this list and an implementation MUST set the \"ResolvedRefs\" condition to \"False\" with the \"InvalidRouteKinds\" reason. If both valid and invalid Route kinds are specified, the implementation MUST reference the valid Route kinds that have been specified.",
 							Type:        []string{"array"},
diff --git a/pkg/generator/main.go b/pkg/generator/main.go
index dc170b88..1149e1a9 100644
--- a/pkg/generator/main.go
+++ b/pkg/generator/main.go
@@ -69,6 +69,8 @@ func main() {
 		log.Fatalf("failed to register markers: %s", err)
 	}
 
+	registerMarkerOverrides(parser.Collector.Registry)
+
 	crd.AddKnownTypes(parser)
 	for _, r := range roots {
 		parser.NeedPackage(r)
diff --git a/pkg/generator/markers.go b/pkg/generator/markers.go
new file mode 100644
index 00000000..ab5f625a
--- /dev/null
+++ b/pkg/generator/markers.go
@@ -0,0 +1,66 @@
+/*
+Copyright 2025 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 main
+
+import (
+	apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+	"sigs.k8s.io/controller-tools/pkg/markers"
+)
+
+type Minimum float64
+
+func (m Minimum) Value() float64 {
+	return float64(m)
+}
+
+//nolint:unparam
+func (m Minimum) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
+	val := m.Value()
+	schema.Minimum = &val
+	return nil
+}
+
+type Maximum float64
+
+func (m Maximum) Value() float64 {
+	return float64(m)
+}
+
+//nolint:unparam
+func (m Maximum) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
+	val := m.Value()
+	schema.Maximum = &val
+	return nil
+}
+
+// kubebuilder Min Max markers are broken with type aliases
+func registerMarkerOverrides(into *markers.Registry) {
+	minMarker, _ := markers.MakeDefinition(
+		"kubebuilder:validation:Minimum",
+		markers.DescribesField,
+		Minimum(0),
+	)
+
+	maxMarker, _ := markers.MakeDefinition(
+		"kubebuilder:validation:Maximum",
+		markers.DescribesField,
+		Maximum(0),
+	)
+
+	into.Register(minMarker) //nolint:errcheck
+	into.Register(maxMarker) //nolint:errcheck
+}
diff --git a/site-src/contributing/index.md b/site-src/contributing/index.md
index 05798beb..323fda89 100644
--- a/site-src/contributing/index.md
+++ b/site-src/contributing/index.md
@@ -37,10 +37,9 @@ questions, discussions.
 
 ## Meetings
 
-Gateway API community meetings happen on the first Tuesday of each month at
-8am Pacific Time (15:00 UTC, [convert to your timezone][8am-pst-convert]) and
-weekly on all subsequent weeks each month on Mondays at 3pm Pacific Time
-(23:00 UTC, [convert to your timezone][3pm-pst-convert]):
+Gateway API community meetings happen on alternating weeks:
+- **Week A**: Mondays at 3pm Pacific Time (23:00 UTC, [convert to your timezone][3pm-pst-convert])
+- **Week B**: Tuesdays at 8am Pacific Time (16:00 UTC, [convert to your timezone][8am-pst-convert])
 
 Being the main meeting for Gateway API, the topics can vary here and often this
 is where new topics and ideas are discussed, including both ingress and service
diff --git a/site-src/implementations.md b/site-src/implementations.md
index 93f6dc2c..46335451 100644
--- a/site-src/implementations.md
+++ b/site-src/implementations.md
@@ -130,6 +130,7 @@ other functions (like managing DNS or creating certificates).
 - [argo-rollouts][22] (alpha)
 - [Knative][24] (alpha)
 - [Kuadrant][26] (GA)
+- [kruise-rollouts][41] (alpha)
 
 [1]:#acnodal-epic
 [2]:#apisix
@@ -170,6 +171,7 @@ other functions (like managing DNS or creating certificates).
 [38]:#google-cloud-service-mesh
 [39]:#kubvernor
 [40]:#agentgateway-with-kgateway
+[41]:#kruise-rollouts
 
 
 [gamma]:mesh/index.md
@@ -269,7 +271,7 @@ performance, and avoid the operational complexity of sidecars. Cilium also
 supports the sidecar proxy model, offering choice to users. As of [Cilium 1.14][cilium114blog],
 Cilium supports Gateway API, passing conformance for v0.7.1.
 
-Cilium is open source and is a CNCF Graduates project.
+Cilium is open source and is a CNCF Graduated project.
 
 If you have questions about Cilium Service Mesh the #service-mesh channel on
 [Cilium Slack][cilium-slack] is a good place to start. For contributing to the development
@@ -685,6 +687,10 @@ For help and support with Kuadrant's implementation please feel free to [create
 [kuadrant-issue-new]:https://github.com/Kuadrant/kuadrant-operator/issues/new
 [kuadrant-slack]:https://kubernetes.slack.com/archives/C05J0D0V525
 
+### OpenKruise Rollouts
+[OpenKruise Rollouts][kruise-rollouts] is a plugin-n-play progressive delivery controller for Kubernetes. It supports several advanced deployment methods such as blue/green and canaries. OpenKruise Rollouts has built-in support for the Gateway API.
+
+[kruise-rollouts]:https://openkruise.io/rollouts/introduction
 
 ## Adding new entries
 



Test patch:
diff --git a/conformance/tests/backendtlspolicy.go b/conformance/tests/backendtlspolicy.go
index 1d556278..fc6c6576 100644
--- a/conformance/tests/backendtlspolicy.go
+++ b/conformance/tests/backendtlspolicy.go
@@ -1,5 +1,5 @@
 /*
-Copyright 2024 The Kubernetes Authors.
+Copyright 2025 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.
@@ -19,9 +19,12 @@ package tests
 import (
 	"testing"
 
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
 	"k8s.io/apimachinery/pkg/types"
 
 	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/apis/v1alpha2"
 	h "sigs.k8s.io/gateway-api/conformance/utils/http"
 	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
@@ -35,7 +38,7 @@ func init() {
 
 var BackendTLSPolicy = suite.ConformanceTest{
 	ShortName:   "BackendTLSPolicy",
-	Description: "A single service that is targeted by a BackendTLSPolicy must successfully complete TLS termination",
+	Description: "BackendTLSPolicy must be used to configure TLS connection between gateway and backend",
 	Features: []features.FeatureName{
 		features.SupportGateway,
 		features.SupportHTTPRoute,
@@ -51,10 +54,25 @@ var BackendTLSPolicy = suite.ConformanceTest{
 		gwAddr := kubernetes.GatewayAndRoutesMustBeAccepted(t, suite.Client, suite.TimeoutConfig, suite.ControllerName, kubernetes.NewGatewayRef(gwNN), &gatewayv1.HTTPRoute{}, false, routeNN)
 		kubernetes.HTTPRouteMustHaveResolvedRefsConditionsTrue(t, suite.Client, suite.TimeoutConfig, routeNN, gwNN)
 
+		policyCond := metav1.Condition{
+			Type:   string(v1alpha2.PolicyConditionAccepted),
+			Status: metav1.ConditionTrue,
+			Reason: string(v1alpha2.PolicyReasonAccepted),
+		}
+
+		validPolicyNN := types.NamespacedName{Name: "normative-test-backendtlspolicy", Namespace: ns}
+		kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, validPolicyNN, gwNN, policyCond)
+
+		invalidPolicyNN := types.NamespacedName{Name: "backendtlspolicy-host-mismatch", Namespace: ns}
+		kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidPolicyNN, gwNN, policyCond)
+
+		invalidCertPolicyNN := types.NamespacedName{Name: "backendtlspolicy-cert-mismatch", Namespace: ns}
+		kubernetes.BackendTLSPolicyMustHaveCondition(t, suite.Client, suite.TimeoutConfig, invalidCertPolicyNN, gwNN, policyCond)
+
 		serverStr := "abc.example.com"
 
-		// Verify that the response to a backend-tls-only call to /backendTLS will return the matching SNI.
-		t.Run("Simple HTTP request targeting BackendTLSPolicy should reach infra-backend", func(t *testing.T) {
+		// Verify that the request sent to Service with valid BackendTLSPolicy should succeed.
+		t.Run("HTTP request sent to Service with valid BackendTLSPolicy should succeed", func(t *testing.T) {
 			h.MakeRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
 				h.ExpectedResponse{
 					Namespace: ns,
@@ -73,8 +91,8 @@ var BackendTLSPolicy = suite.ConformanceTest{
 		if err != nil {
 			t.Fatalf("unexpected error finding TLS secret: %v", err)
 		}
-		// Verify that the response to a re-encrypted call to /backendTLS will return the matching SNI.
-		t.Run("Re-encrypt HTTPS request targeting BackendTLSPolicy should reach infra-backend", func(t *testing.T) {
+		// Verify that the request to a re-encrypted call to /backendTLS should succeed.
+		t.Run("Re-encrypt HTTPS request sent to Service with valid BackendTLSPolicy should succeed", func(t *testing.T) {
 			tls.MakeTLSRequestAndExpectEventuallyConsistentResponse(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr, cPem, keyPem, serverStr,
 				h.ExpectedResponse{
 					Namespace: ns,
@@ -86,5 +104,31 @@ var BackendTLSPolicy = suite.ConformanceTest{
 					Response: h.Response{StatusCode: 200},
 				})
 		})
+
+		// Verify that the request sent to a Service targeted by a BackendTLSPolicy with mismatched host will fail.
+		t.Run("HTTP request sent to Service targeted by BackendTLSPolicy with mismatched hostname should return an HTTP error", func(t *testing.T) {
+			h.MakeRequestAndExpectFailure(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendTLSHostMismatch",
+						SNI:  serverStr,
+					},
+				})
+		})
+
+		// Verify that request sent to Service targeted by BackendTLSPolicy with mismatched cert should failed.
+		t.Run("HTTP request send to Service targeted by BackendTLSPolicy with mismatched cert should return HTTP error", func(t *testing.T) {
+			h.MakeRequestAndExpectFailure(t, suite.RoundTripper, suite.TimeoutConfig, gwAddr,
+				h.ExpectedResponse{
+					Namespace: ns,
+					Request: h.Request{
+						Host: serverStr,
+						Path: "/backendTLSCertMismatch",
+						SNI:  serverStr,
+					},
+				})
+		})
 	},
 }
diff --git a/conformance/tests/backendtlspolicy.yaml b/conformance/tests/backendtlspolicy.yaml
index 91f6a590..e048cc2e 100644
--- a/conformance/tests/backendtlspolicy.yaml
+++ b/conformance/tests/backendtlspolicy.yaml
@@ -31,25 +31,6 @@ spec:
       kinds:
       - kind: HTTPRoute
 ---
-apiVersion: gateway.networking.k8s.io/v1alpha3
-kind: BackendTLSPolicy
-metadata:
-  name: normative-test-backendtlspolicy
-  namespace: gateway-conformance-infra
-spec:
-  targetRefs:
-  - group: ""
-    kind: Service
-    name: "backendtlspolicy-test"
-    sectionName: "btls"
-  validation:
-    caCertificateRefs:
-    - group: ""
-      kind: ConfigMap
-      # This secret is generated dynamically by the test suite.
-      name: "backend-tls-checks-certificate"
-    hostname: "abc.example.com"
----
 apiVersion: gateway.networking.k8s.io/v1
 kind: HTTPRoute
 metadata:
@@ -71,6 +52,24 @@ spec:
     - path:
         type: Exact
         value: /backendTLS
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backendtlspolicy-host-mismatch-test
+      port: 443
+    matches:
+    - path:
+        type: Exact
+        value: /backendTLSHostMismatch
+  - backendRefs:
+    - group: ""
+      kind: Service
+      name: backendtlspolicy-cert-mismatch-test
+      port: 443
+    matches:
+    - path:
+        type: Exact
+        value: /backendTLSCertMismatch
 ---
 apiVersion: v1
 kind: Service
@@ -86,6 +85,36 @@ spec:
     port: 443
     targetPort: 8443
 ---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-host-mismatch-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: backendtlspolicy-test
+  ports:
+  - name: "btls"
+    protocol: TCP
+    appProtocol: HTTPS
+    port: 443
+    targetPort: 8443
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: backendtlspolicy-cert-mismatch-test
+  namespace: gateway-conformance-infra
+spec:
+  selector:
+    app: backendtlspolicy-test
+  ports:
+  - name: "btls"
+    protocol: TCP
+    appProtocol: HTTPS
+    port: 443
+    targetPort: 8443
+---
 # Deployment must not be applied until after the secret is generated.
 apiVersion: apps/v1
 kind: Deployment
@@ -151,3 +180,60 @@ spec:
             path: crt
           - key: tls.key
             path: key
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: normative-test-backendtlspolicy
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: "backendtlspolicy-test"
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-checks-certificate"
+    hostname: "abc.example.com"
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: backendtlspolicy-host-mismatch
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: "backendtlspolicy-host-mismatch-test"
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-checks-certificate"
+    hostname: "mismatch.example.com"
+---
+apiVersion: gateway.networking.k8s.io/v1alpha3
+kind: BackendTLSPolicy
+metadata:
+  name: backendtlspolicy-cert-mismatch
+  namespace: gateway-conformance-infra
+spec:
+  targetRefs:
+  - group: ""
+    kind: Service
+    name: "backendtlspolicy-cert-mismatch-test"
+    sectionName: "btls"
+  validation:
+    caCertificateRefs:
+    - group: ""
+      kind: ConfigMap
+      # This secret is generated dynamically by the test suite.
+      name: "backend-tls-mismatch-certificate"
+    hostname: "abc.example.com"
diff --git a/conformance/tests/httproute-weight.go b/conformance/tests/httproute-weight.go
index 2c1a520d..fa85deb9 100644
--- a/conformance/tests/httproute-weight.go
+++ b/conformance/tests/httproute-weight.go
@@ -91,7 +91,6 @@ func testDistribution(t *testing.T, suite *suite.ConformanceTestSuite, gwAddr st
 		g               errgroup.Group
 		seenMutex       sync.Mutex
 		seen            = make(map[string]float64, 3 /* number of backends */)
-		req             = http.MakeRequest(t, &expected, gwAddr, "HTTP", "http")
 		expectedWeights = map[string]float64{
 			"infra-backend-v1": 0.7,
 			"infra-backend-v2": 0.3,
@@ -101,6 +100,11 @@ func testDistribution(t *testing.T, suite *suite.ConformanceTestSuite, gwAddr st
 	g.SetLimit(concurrentRequests)
 	for i := 0.0; i < totalRequests; i++ {
 		g.Go(func() error {
+			uniqueExpected := expected
+			if err := http.AddEntropy(&uniqueExpected); err != nil {
+				return fmt.Errorf("error adding entropy: %w", err)
+			}
+			req := http.MakeRequest(t, &uniqueExpected, gwAddr, "HTTP", "http")
 			cReq, cRes, err := roundTripper.CaptureRoundTrip(req)
 			if err != nil {
 				return fmt.Errorf("failed to roundtrip request: %w", err)
diff --git a/conformance/tests/mesh/httproute-weight.go b/conformance/tests/mesh/httproute-weight.go
index cc296d92..844d5471 100644
--- a/conformance/tests/mesh/httproute-weight.go
+++ b/conformance/tests/mesh/httproute-weight.go
@@ -18,16 +18,13 @@ package meshtests
 
 import (
 	"cmp"
-	"crypto/rand"
 	"errors"
 	"fmt"
 	"math"
-	"math/big"
 	"slices"
 	"strings"
 	"sync"
 	"testing"
-	"time"
 
 	"golang.org/x/sync/errgroup"
 
@@ -93,7 +90,7 @@ func testDistribution(t *testing.T, client echo.MeshPod, expected http.ExpectedR
 	for i := 0.0; i < totalRequests; i++ {
 		g.Go(func() error {
 			uniqueExpected := expected
-			if err := addEntropy(&uniqueExpected); err != nil {
+			if err := http.AddEntropy(&uniqueExpected); err != nil {
 				return fmt.Errorf("error adding entropy: %w", err)
 			}
 			_, cRes, err := client.CaptureRequestResponseAndCompare(t, uniqueExpected)
@@ -148,54 +145,3 @@ func testDistribution(t *testing.T, client echo.MeshPod, expected http.ExpectedR
 	})
 	return errors.Join(errs...)
 }
-
-// addEntropy adds jitter to the request by adding either a delay up to 1 second, or a random header value, or both.
-func addEntropy(exp *http.ExpectedResponse) error {
-	randomNumber := func(limit int64) (*int64, error) {
-		number, err := rand.Int(rand.Reader, big.NewInt(limit))
-		if err != nil {
-			return nil, err
-		}
-		n := number.Int64()
-		return &n, nil
-	}
-
-	// adds a delay
-	delay := func(limit int64) error {
-		randomSleepDuration, err := randomNumber(limit)
-		if err != nil {
-			return err
-		}
-		time.Sleep(time.Duration(*randomSleepDuration) * time.Millisecond)
-		return nil
-	}
-	// adds random header value
-	randomHeader := func(limit int64) error {
-		randomHeaderValue, err := randomNumber(limit)
-		if err != nil {
-			return err
-		}
-		exp.Request.Headers = make(map[string]string)
-		exp.Request.Headers["X-Jitter"] = fmt.Sprintf("%d", *randomHeaderValue)
-		return nil
-	}
-
-	random, err := randomNumber(3)
-	if err != nil {
-		return err
-	}
-
-	switch *random {
-	case 0:
-		return delay(1000)
-	case 1:
-		return randomHeader(10000)
-	case 2:
-		if err := delay(1000); err != nil {
-			return err
-		}
-		return randomHeader(10000)
-	default:
-		return fmt.Errorf("invalid random value: %d", *random)
-	}
-}
diff --git a/conformance/utils/suite/suite_test.go b/conformance/utils/suite/suite_test.go
index 311da616..778afa71 100644
--- a/conformance/utils/suite/suite_test.go
+++ b/conformance/utils/suite/suite_test.go
@@ -22,7 +22,6 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
-
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/util/sets"
@@ -545,9 +544,8 @@ func TestGWCPublishedMeshFeatures(t *testing.T) {
 			},
 			SupportedFeatures: featureNamesToSet([]string{
 				string(features.SupportGateway),
-				string(features.SupportGatewayStaticAddresses),
+				string(features.SupportMesh),
 				string(features.SupportMeshClusterIPMatching),
-				string(features.SupportMeshConsumerRoute),
 			}),
 		},
 	}
@@ -568,9 +566,12 @@ func TestGWCPublishedMeshFeatures(t *testing.T) {
 		Client:            fakeClient,
 	}
 
-	_, err := NewConformanceTestSuite(options)
-	if err == nil {
-		t.Fatalf("expected an error but got nil")
+	suite, err := NewConformanceTestSuite(options)
+	if err != nil {
+		t.Fatalf("error initializing conformance suite: %v", err)
+	}
+	if suite.SupportedFeatures.HasAny(features.SetsToNamesSet(features.MeshCoreFeatures, features.MeshExtendedFeatures).UnsortedList()...) {
+		t.Errorf("Mesh features should be skipped, got: %v", suite.SupportedFeatures.UnsortedList())
 	}
 }
 
diff --git a/pkg/test/cel/main_test.go b/pkg/test/cel/main_test.go
index 3ba7de1d..e4c656f7 100644
--- a/pkg/test/cel/main_test.go
+++ b/pkg/test/cel/main_test.go
@@ -19,7 +19,7 @@ package main
 import (
 	"fmt"
 	"os"
-	"path"
+	"path/filepath"
 	"strings"
 	"testing"
 
@@ -29,34 +29,84 @@ import (
 	"sigs.k8s.io/gateway-api/apis/v1beta1"
 	apisxv1alpha1 "sigs.k8s.io/gateway-api/apisx/v1alpha1"
 
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"k8s.io/client-go/rest"
 	"k8s.io/client-go/tools/clientcmd"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/envtest"
 )
 
 var k8sClient client.Client
 
 func TestMain(m *testing.M) {
+	scheme := runtime.NewScheme()
+	var restConfig *rest.Config
+	var testEnv *envtest.Environment
+	var err error
+
+	v1alpha3.Install(scheme)
+	v1alpha2.Install(scheme)
+	v1beta1.Install(scheme)
+	v1.Install(scheme)
+	apisxv1alpha1.Install(scheme)
+
+	// Add core APIs in case we refer secrets, services and configmaps
+	corev1.AddToScheme(scheme)
+
+	// If one wants to use a local cluster, a KUBECONFIG envvar should be passed,
+	// otherwise testenv will be used
 	kubeconfig := os.Getenv("KUBECONFIG")
-	if kubeconfig == "" {
-		kubeconfig = path.Join(os.Getenv("HOME"), ".kube/config")
+	if kubeconfig != "" {
+		restConfig, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
+		if err != nil {
+			panic(fmt.Sprintf("Failed to get restConfig from BuildConfigFromFlags: %v", err))
+		}
+	} else {
+		// The version used here MUST reflect the available versions at
+		// controller-runtime repo: https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/HEAD/envtest-releases.yaml
+		// If the envvar is not passed, the latest GA will be used
+		k8sVersion := os.Getenv("K8S_VERSION")
+
+		crdChannel := "standard"
+		if requestedCRDChannel, ok := os.LookupEnv("CRD_CHANNEL"); ok {
+			crdChannel = requestedCRDChannel
+		}
+
+		testEnv = &envtest.Environment{
+			Scheme:                      scheme,
+			ErrorIfCRDPathMissing:       true,
+			DownloadBinaryAssets:        true,
+			DownloadBinaryAssetsVersion: k8sVersion,
+			CRDInstallOptions: envtest.CRDInstallOptions{
+				Paths: []string{
+					filepath.Join("..", "..", "..", "config", "crd", crdChannel),
+				},
+				CleanUpAfterUse: true,
+			},
+		}
+
+		restConfig, err = testEnv.Start()
+		if err != nil {
+			panic(fmt.Sprintf("Error initializing test environment: %v", err))
+		}
 	}
 
-	restConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
+	k8sClient, err = client.New(restConfig, client.Options{
+		Scheme: scheme,
+	})
 	if err != nil {
-		panic(fmt.Sprintf("Failed to get restConfig from BuildConfigFromFlags: %v", err))
+		panic(fmt.Sprintf("Error initializing Kubernetes client: %v", err))
 	}
 
-	k8sClient, err = client.New(restConfig, client.Options{})
-	if err != nil {
-		panic(fmt.Sprintf("Error initializing Kubernetes client: %v", err))
+	rc := m.Run()
+	if testEnv != nil {
+		if err := testEnv.Stop(); err != nil {
+			panic(fmt.Sprintf("error stopping test environment: %v", err))
+		}
 	}
-	v1alpha3.Install(k8sClient.Scheme())
-	v1alpha2.Install(k8sClient.Scheme())
-	v1beta1.Install(k8sClient.Scheme())
-	v1.Install(k8sClient.Scheme())
-	apisxv1alpha1.Install(k8sClient.Scheme())
 
-	os.Exit(m.Run())
+	os.Exit(rc)
 }
 
 func ptrTo[T any](a T) *T {
diff --git a/pkg/test/crd/crd_test.go b/pkg/test/crd/crd_test.go
new file mode 100644
index 00000000..9becc1aa
--- /dev/null
+++ b/pkg/test/crd/crd_test.go
@@ -0,0 +1,177 @@
+/*
+Copyright 2025 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 crd_test
+
+import (
+	"fmt"
+	"io/fs"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	corev1 "k8s.io/api/core/v1"
+	"k8s.io/apimachinery/pkg/runtime"
+	"sigs.k8s.io/controller-runtime/pkg/envtest"
+
+	v1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/apis/v1alpha2"
+	"sigs.k8s.io/gateway-api/apis/v1alpha3"
+	"sigs.k8s.io/gateway-api/apis/v1beta1"
+	apisxv1alpha1 "sigs.k8s.io/gateway-api/apisx/v1alpha1"
+)
+
+// This test is a replacement for the previously existing tests inside
+// tests-crds-validation.sh.
+// Instead of relying on a KinD cluster, we can rely on an `envtest` which
+// usually is faster to create and teardown the environment
+func TestCRDValidation(t *testing.T) {
+	scheme := runtime.NewScheme()
+	var testEnv *envtest.Environment
+	var err error
+
+	// We will extract these from envTest and create our own exec.Cmd to reproduce
+	// a user doing "kubectl" commands
+	var kubectlLocation, kubeconfigLocation string
+
+	crdChannel := "standard"
+
+	v1alpha3.Install(scheme)
+	v1alpha2.Install(scheme)
+	v1beta1.Install(scheme)
+	v1.Install(scheme)
+	apisxv1alpha1.Install(scheme)
+
+	// Add core APIs in case we refer secrets, services and configmaps
+	corev1.AddToScheme(scheme)
+
+	// The version used here MUST reflect the available versions at
+	// controller-runtime repo: https://raw.githubusercontent.com/kubernetes-sigs/controller-tools/HEAD/envtest-releases.yaml
+	// If the envvar is not passed, the latest GA will be used
+	k8sVersion := os.Getenv("K8S_VERSION")
+	if requestedCRDChannel, ok := os.LookupEnv("CRD_CHANNEL"); ok {
+		crdChannel = requestedCRDChannel
+	}
+
+	t.Run("should be able to start test environment", func(_ *testing.T) {
+		testEnv = &envtest.Environment{
+			Scheme:                      scheme,
+			ErrorIfCRDPathMissing:       true,
+			DownloadBinaryAssets:        true,
+			DownloadBinaryAssetsVersion: k8sVersion,
+			CRDInstallOptions: envtest.CRDInstallOptions{
+				Paths: []string{
+					filepath.Join("..", "..", "..", "config", "crd", crdChannel),
+				},
+				CleanUpAfterUse: true,
+			},
+		}
+
+		_, err = testEnv.Start()
+		if err != nil {
+			panic(fmt.Sprintf("Error initializing test environment: %v", err))
+		}
+	})
+
+	t.Cleanup(func() {
+		require.NoError(t, testEnv.Stop())
+	})
+
+	t.Run("should be able to set kubectl and kubeconfig and connect to the cluster", func(t *testing.T) {
+		kubectlLocation = testEnv.ControlPlane.KubectlPath
+		require.NotEmpty(t, kubectlLocation)
+
+		kubeconfigLocation = fmt.Sprintf("%s/kubeconfig", filepath.Dir(kubectlLocation))
+		require.NoError(t, os.WriteFile(kubeconfigLocation, testEnv.KubeConfig, 0o600))
+
+		apiResources, err := executeKubectlCommand(t, kubectlLocation, kubeconfigLocation, []string{"api-resources"})
+		require.NoError(t, err)
+		require.Contains(t, apiResources, "gateway.networking.k8s.io/v1")
+	})
+
+	t.Run("should be able to install standard examples", func(t *testing.T) {
+		output, err := executeKubectlCommand(t, kubectlLocation, kubeconfigLocation, []string{"apply", "--recursive", "-f", filepath.Join("..", "..", "..", "examples", "standard")})
+		assert.NoError(t, err, "output", output)
+	})
+
+	t.Run("should be able to install experimental examples", func(t *testing.T) {
+		if crdChannel != "experimental" {
+			t.Skipf("experimental channel not being tested")
+		}
+		output, err := executeKubectlCommand(t, kubectlLocation, kubeconfigLocation, []string{"apply", "--recursive", "-f", filepath.Join("..", "..", "..", "examples", "experimental")})
+		assert.NoError(t, err, "output", output)
+	})
+
+	t.Run("should expect an error in case of validation failure", func(t *testing.T) {
+		files, err := getInvalidExamplesFiles(t, crdChannel)
+		require.NoError(t, err)
+
+		for _, example := range files {
+			t.Run(fmt.Sprintf("validate example %s", example), func(t *testing.T) {
+				output, err := executeKubectlCommand(t, kubectlLocation, kubeconfigLocation, []string{"apply", "-f", example})
+				require.Error(t, err)
+				assert.True(t, expectedValidationError(output), "output does not contain the expected error", output)
+			})
+		}
+	})
+}
+
+func expectedValidationError(cmdoutput string) bool {
+	return strings.Contains(cmdoutput, "is invalid") ||
+		strings.Contains(cmdoutput, "missing required field") ||
+		strings.Contains(cmdoutput, "denied request") ||
+		strings.Contains(cmdoutput, "Invalid value")
+}
+
+func executeKubectlCommand(t *testing.T, kubectl, kubeconfig string, args []string) (string, error) {
+	t.Helper()
+
+	cacheDir := filepath.Dir(kubeconfig)
+	args = append([]string{"--cache-dir", cacheDir}, args...)
+
+	cmd := exec.Command(kubectl, args...)
+	cmd.Env = []string{
+		fmt.Sprintf("KUBECONFIG=%s", kubeconfig),
+	}
+
+	output, err := cmd.CombinedOutput()
+	return string(output), err
+}
+
+func getInvalidExamplesFiles(t *testing.T, crdChannel string) ([]string, error) {
+	t.Helper()
+
+	var files []string
+	err := filepath.WalkDir(filepath.Join("..", "..", "..", "hack", "invalid-examples"), func(path string, d fs.DirEntry, err error) error {
+		if err != nil {
+			return err
+		}
+
+		if crdChannel == "standard" && strings.Contains(path, "experimental") {
+			return nil
+		}
+
+		if !d.IsDir() && filepath.Ext(path) == ".yaml" {
+			files = append(files, path)
+		}
+		return nil
+	})
+	return files, err
+}