Repository: kubernetes-sigs/gateway-api

Issue:
Improving distribution tests in conformance
On https://github.com/kubernetes-sigs/gateway-api/pull/3827#discussion_r2123121430

@guicassolato suggested the below: 

> Worth adding some entropy to each iteration to mitigate the risk of coordinated execution perhaps? For example: introducing jitter, randomising the payload, or anything else that varies the sample across iterations (without affecting expected weight distribution).

It would be nice to have something like thig

/good-first-issue

Hints from issue comments:
@k8s-ci-robot: @LiorLieberman: 
	This request has been marked as suitable for new contributors.

### Guidelines
Please ensure that the issue body includes answers to the following questions:
- Why are we solving this issue?
- To address this issue, are there any code changes? If there are code changes, what needs to be done in the code and what places can the assignee treat as reference points?
- Does this issue have zero to low barrier of entry?
- How can the assignee reach out to you for help?


For more details on the requirements of such an issue, please see [here](https://git.k8s.io/community/contributors/guide/help-wanted.md#good-first-issue) and ensure that they are met.

If this request no longer meets these requirements, the label can be removed
by commenting with the `/remove-good-first-issue` command.


<details>

In response to [this](https://github.com/kubernetes-sigs/gateway-api/issues/3832):

>On https://github.com/kubernetes-sigs/gateway-api/pull/3827#discussion_r2123121430
>
>@guicassolato suggested the below: 
>
>> Worth adding some entropy to each iteration to mitigate the risk of coordinated execution perhaps? For example: introducing jitter, randomising the payload, or anything else that varies the sample across iterations (without affecting expected weight distribution).
>
>It would be nice to have something like thig
>
>/good-first-issue


Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>@carsontham: /assign@chris-kaiser-7: Can I help with this issue?@LiorLieberman: Sure!
/assign @chris-kaiser-7 @carsontham: hi @LiorLieberman, my apologies for not submitting a PR yet, but I was spending the past few days trying to understand the tests and also running the test locally.

So far, I've ran the tests using the below command, without making any changes ( I wanted to make sure I was running the tests correctly and not break anything ).
```
go test -v ./conformance \
--run TestConformance/MeshHTTPRouteWeight \
--supported-features=Mesh,HTTPRoute
```

And the test is returning me failure even without adding any entropy: 

```
    httproute-weight.go:64: Traffic distribution test failed (10/10): backend "echo-v1" weighted traffic of 0.524 not within tolerance 0.7 (+/-0.050000)
        backend "echo-v2" weighted traffic of 0.476 not within tolerance 0.3 (+/-0.050000)
    httproute-weight.go:69: Weighted distribution tests failed
=== NAME  TestConformance/MeshHTTPRouteWeight
    apply.go:283: 2025-06-10T18:05:28.312926+08:00: Deleting mesh-weighted-backends HTTPRoute
=== NAME  TestConformance
    apply.go:283: 2025-06-10T18:05:28.317196+08:00: Deleting echo-v1 Deployment
    apply.go:283: 2025-06-10T18:05:28.320049+08:00: Deleting gateway-conformance-mesh-consumer Namespace
    apply.go:283: 2025-06-10T18:05:28.322049+08:00: Deleting echo Service
    apply.go:283: 2025-06-10T18:05:28.330848+08:00: Deleting echo-v2 Service
    apply.go:283: 2025-06-10T18:05:28.341497+08:00: Deleting echo-v2 Deployment
    apply.go:283: 2025-06-10T18:05:28.345876+08:00: Deleting echo-v1 Service
    apply.go:283: 2025-06-10T18:05:28.352877+08:00: Deleting echo-v1 Deployment
    apply.go:283: 2025-06-10T18:05:28.357337+08:00: Deleting gateway-conformance-mesh Namespace
--- FAIL: TestConformance (73.35s)
    --- FAIL: TestConformance/MeshHTTPRouteWeight (71.08s)
        --- FAIL: TestConformance/MeshHTTPRouteWeight/Requests_should_have_a_distribution_that_matches_the_weight (71.06s)
```

I'm not sure if I'm running the tests wrongly, but could you point me to the right direction? thanks !@LiorLieberman: @carsontham Sorry! that was last night my time and I did not see that you already assinged. 

Please go ahead, open a PR and I can help you debug it on the PR.

@chris-kaiser-7 - I recommend waiting with this one since @carsontham is already working on it. 

/assign @carsontham @carsontham: hey @LiorLieberman no worries at all! will come up with a PR soon :) Thanks alot!@chris-kaiser-7: /unassign

Solution patch:
diff --git a/conformance/apis/v1/conformancereport.go b/conformance/apis/v1/conformancereport.go
index 7f4f4d53..dcea92df 100644
--- a/conformance/apis/v1/conformancereport.go
+++ b/conformance/apis/v1/conformancereport.go
@@ -50,6 +50,10 @@ type ConformanceReport struct {
 	// SucceededProvisionalTests is a list of the names of the provisional tests that
 	// have been successfully run.
 	SucceededProvisionalTests []string `json:"succeededProvisionalTests,omitempty"`
+
+	// InferredSupportedFeatures indicates whether the supported features were
+	// automatically detected by the conformance suite.
+	InferredSupportedFeatures bool `json:"inferredSupportedFeatures"`
 }
 
 // Implementation provides metadata information on the downstream
diff --git a/conformance/conformance.go b/conformance/conformance.go
index ce264a94..12e58849 100644
--- a/conformance/conformance.go
+++ b/conformance/conformance.go
@@ -29,11 +29,14 @@ import (
 	"sigs.k8s.io/gateway-api/conformance/tests"
 	conformanceconfig "sigs.k8s.io/gateway-api/conformance/utils/config"
 	"sigs.k8s.io/gateway-api/conformance/utils/flags"
+
 	"sigs.k8s.io/gateway-api/conformance/utils/suite"
 
 	"github.com/stretchr/testify/require"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
+
 	clientset "k8s.io/client-go/kubernetes"
+
 	"sigs.k8s.io/controller-runtime/pkg/client"
 	"sigs.k8s.io/controller-runtime/pkg/client/config"
 	"sigs.k8s.io/yaml"
@@ -63,6 +66,7 @@ func DefaultOptions(t *testing.T) suite.ConformanceOptions {
 
 	supportedFeatures := suite.ParseSupportedFeatures(*flags.SupportedFeatures)
 	exemptFeatures := suite.ParseSupportedFeatures(*flags.ExemptFeatures)
+
 	skipTests := suite.ParseSkipTests(*flags.SkipTests)
 	namespaceLabels := suite.ParseKeyValuePairs(*flags.NamespaceLabels)
 	namespaceAnnotations := suite.ParseKeyValuePairs(*flags.NamespaceAnnotations)
@@ -144,6 +148,7 @@ func logOptions(t *testing.T, opts suite.ConformanceOptions) {
 	t.Logf("  Enable All Features: %t", opts.EnableAllSupportedFeatures)
 	t.Logf("  Supported Features: %v", opts.SupportedFeatures.UnsortedList())
 	t.Logf("  ExemptFeatures: %v", opts.ExemptFeatures.UnsortedList())
+	t.Logf("  ConformanceProfiles: %v", opts.ConformanceProfiles.UnsortedList())
 }
 
 func writeReport(logf func(string, ...any), report confv1.ConformanceReport, output string) error {
diff --git a/conformance/reports/v1.3.0/kgateway/README.md b/conformance/reports/v1.3.0/kgateway/README.md
new file mode 100644
index 00000000..ddd082e5
--- /dev/null
+++ b/conformance/reports/v1.3.0/kgateway/README.md
@@ -0,0 +1,40 @@
+# kgateway
+
+## Table of contents
+
+| API channel  | Implementation version                                                        | Mode    | Report                                                    |
+|--------------|-------------------------------------------------------------------------------|---------|-----------------------------------------------------------|
+| experimental | [main](https://github.com/kgateway-dev/kgateway) | default | [Link](./v2.1.0-main-report.yaml) |
+
+## Reproduce
+
+### Steps
+
+1. Clone the kgateway repository:
+
+   ```sh
+   git clone https://github.com/kgateway-dev/kgateway.git && cd kgateway
+   ```
+
+2. Override the version Makefile variable:
+
+   > Note: The main branch defaults to version `1.0.1-dev` for Helm chart validation purposes. For conformance testing,
+   > we need to override this with a more descriptive version that reflects the main branch:
+
+   ```sh
+   export VERSION="v2.1.0-main"
+   ```
+
+3. Bootstrap a KinD cluster:
+
+   ```sh
+   make run
+   ```
+
+4. Run the conformance tests:
+
+   ```sh
+   make conformance
+   ```
+
+5. View and verify the conformance report: `cat _test/conformance/v2.1.0-main-report.yaml`
diff --git a/conformance/reports/v1.3.0/kgateway/v2.1.0-main-report.yaml b/conformance/reports/v1.3.0/kgateway/v2.1.0-main-report.yaml
new file mode 100644
index 00000000..67249032
--- /dev/null
+++ b/conformance/reports/v1.3.0/kgateway/v2.1.0-main-report.yaml
@@ -0,0 +1,53 @@
+apiVersion: gateway.networking.k8s.io/v1
+date: "2025-06-18T15:07:19-04:00"
+gatewayAPIChannel: experimental
+gatewayAPIVersion: v1.3.0
+implementation:
+  contact:
+  - github.com/kgateway-dev/kgateway/issues/new/choose
+  organization: kgateway-dev
+  project: kgateway
+  url: github.com/kgateway-dev/kgateway
+  version: v2.1.0-main
+kind: ConformanceReport
+mode: default
+profiles:
+- core:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 33
+      Skipped: 0
+  extended:
+    result: success
+    statistics:
+      Failed: 0
+      Passed: 13
+      Skipped: 0
+    supportedFeatures:
+    - HTTPRouteBackendProtocolH2C
+    - HTTPRouteBackendProtocolWebSocket
+    - HTTPRouteBackendTimeout
+    - HTTPRouteHostRewrite
+    - HTTPRouteMethodMatching
+    - HTTPRoutePathRedirect
+    - HTTPRoutePathRewrite
+    - HTTPRoutePortRedirect
+    - HTTPRouteQueryParamMatching
+    - HTTPRouteRequestMirror
+    - HTTPRouteRequestTimeout
+    - HTTPRouteResponseHeaderModification
+    - HTTPRouteSchemeRedirect
+    unsupportedFeatures:
+    - GatewayAddressEmpty
+    - GatewayHTTPListenerIsolation
+    - GatewayInfrastructurePropagation
+    - GatewayPort8080
+    - GatewayStaticAddresses
+    - HTTPRouteBackendRequestHeaderModification
+    - HTTPRouteDestinationPortMatching
+    - HTTPRouteParentRefPort
+    - HTTPRouteRequestMultipleMirrors
+    - HTTPRouteRequestPercentageMirror
+  name: GATEWAY-HTTP
+  summary: Core tests succeeded. Extended tests succeeded.
diff --git a/conformance/utils/suite/conformance.go b/conformance/utils/suite/conformance.go
index 3bbbbc1c..12db14d6 100644
--- a/conformance/utils/suite/conformance.go
+++ b/conformance/utils/suite/conformance.go
@@ -21,8 +21,6 @@ import (
 	"strings"
 	"testing"
 
-	"k8s.io/apimachinery/pkg/util/sets"
-
 	"sigs.k8s.io/gateway-api/conformance/utils/tlog"
 	"sigs.k8s.io/gateway-api/pkg/features"
 )
@@ -81,11 +79,11 @@ func (test *ConformanceTest) Run(t *testing.T, suite *ConformanceTestSuite) {
 
 // ParseSupportedFeatures parses flag arguments and converts the string to
 // sets.Set[features.FeatureName]
-func ParseSupportedFeatures(f string) sets.Set[features.FeatureName] {
+func ParseSupportedFeatures(f string) FeaturesSet {
 	if f == "" {
 		return nil
 	}
-	res := sets.Set[features.FeatureName]{}
+	res := FeaturesSet{}
 	for _, value := range strings.Split(f, ",") {
 		res.Insert(features.FeatureName(value))
 	}
diff --git a/conformance/utils/suite/reports.go b/conformance/utils/suite/reports.go
index 4b03d677..4efcc4e7 100644
--- a/conformance/utils/suite/reports.go
+++ b/conformance/utils/suite/reports.go
@@ -22,7 +22,6 @@ import (
 	"k8s.io/apimachinery/pkg/util/sets"
 
 	confv1 "sigs.k8s.io/gateway-api/conformance/apis/v1"
-	"sigs.k8s.io/gateway-api/pkg/features"
 )
 
 // -----------------------------------------------------------------------------
@@ -107,7 +106,7 @@ func (p profileReportsMap) list() (profileReports []confv1.ProfileReport) {
 	return
 }
 
-func (p profileReportsMap) compileResults(supportedFeaturesMap map[ConformanceProfileName]sets.Set[features.FeatureName], unsupportedFeaturesMap map[ConformanceProfileName]sets.Set[features.FeatureName]) {
+func (p profileReportsMap) compileResults(supportedFeaturesMap map[ConformanceProfileName]FeaturesSet, unsupportedFeaturesMap map[ConformanceProfileName]FeaturesSet) {
 	for key, report := range p {
 		// report the overall result for core features
 		switch {
@@ -162,7 +161,8 @@ func (p profileReportsMap) compileResults(supportedFeaturesMap map[ConformancePr
 // isTestExtended determines if a provided test is considered to be supported
 // at an extended level of support given the provided conformance profile.
 //
-// TODO: right now the tests themselves don't indicate the conformance
+// TODO(#3759) Update this method to be based on Features inferred.
+// Right now the tests themselves don't indicate the conformance
 // support level associated with them. The only way we have right now
 // in this prototype to know whether a test belongs to any particular
 // conformance level is to compare the features needed for the test to
diff --git a/conformance/utils/suite/suite.go b/conformance/utils/suite/suite.go
index e6a5cb12..f1164fa2 100644
--- a/conformance/utils/suite/suite.go
+++ b/conformance/utils/suite/suite.go
@@ -31,11 +31,13 @@ import (
 	"github.com/stretchr/testify/require"
 	apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
 	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/sets"
 	clientset "k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/rest"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
 	"sigs.k8s.io/gateway-api/apis/v1beta1"
 	confv1 "sigs.k8s.io/gateway-api/conformance/apis/v1"
 	"sigs.k8s.io/gateway-api/conformance/utils/config"
@@ -69,7 +71,7 @@ type ConformanceTestSuite struct {
 	BaseManifests            string
 	MeshManifests            string
 	Applier                  kubernetes.Applier
-	SupportedFeatures        sets.Set[features.FeatureName]
+	SupportedFeatures        FeaturesSet
 	TimeoutConfig            config.TimeoutConfig
 	SkipTests                sets.Set[string]
 	SkipProvisionalTests     bool
@@ -79,6 +81,11 @@ type ConformanceTestSuite struct {
 	UsableNetworkAddresses   []v1beta1.GatewaySpecAddress
 	UnusableNetworkAddresses []v1beta1.GatewaySpecAddress
 
+	// If SupportedFeatures are automatically determined from GWC Status.
+	// This will be required to report in future iterations as the passing
+	// will be determined based on this.
+	isInferredSupportedFeatures bool
+
 	// mode is the operating mode of the implementation.
 	// The default value for it is "default".
 	mode string
@@ -142,8 +149,8 @@ type ConformanceOptions struct {
 	// CleanupBaseResources indicates whether or not the base test
 	// resources such as Gateways should be cleaned up after the run.
 	CleanupBaseResources       bool
-	SupportedFeatures          sets.Set[features.FeatureName]
-	ExemptFeatures             sets.Set[features.FeatureName]
+	SupportedFeatures          FeaturesSet
+	ExemptFeatures             FeaturesSet
 	EnableAllSupportedFeatures bool
 	TimeoutConfig              config.TimeoutConfig
 	// SkipTests contains all the tests not to be run and can be used to opt out
@@ -172,6 +179,8 @@ type ConformanceOptions struct {
 	ConformanceProfiles sets.Set[ConformanceProfileName]
 }
 
+type FeaturesSet = sets.Set[features.FeatureName]
+
 const (
 	// undefinedKeyword is set in the ConformanceReport "GatewayAPIVersion" and
 	// "GatewayAPIChannel" fields in case it's not possible to figure out the actual
@@ -181,16 +190,23 @@ const (
 
 // NewConformanceTestSuite is a helper to use for creating a new ConformanceTestSuite.
 func NewConformanceTestSuite(options ConformanceOptions) (*ConformanceTestSuite, error) {
-	// test suite callers are required to provide either:
-	// - one conformance profile via the flag '-conformance-profiles'
-	// - a list of supported features via the flag '-supported-features'
-	// - an explicit test to run via the flag '-run-test'
-	// - all features are being tested via the flag '-all-features'
-	if options.SupportedFeatures.Len() == 0 &&
-		options.ConformanceProfiles.Len() == 0 &&
-		!options.EnableAllSupportedFeatures &&
-		options.RunTest == "" {
-		return nil, fmt.Errorf("no conformance profile, supported features, explicit tests were provided so no tests could be selected")
+	supportedFeatures := options.SupportedFeatures.Difference(options.ExemptFeatures)
+	isInferred := false
+	switch {
+	case options.EnableAllSupportedFeatures:
+		supportedFeatures = features.SetsToNamesSet(features.AllFeatures)
+	case shouldInferSupportedFeatures(&options):
+		var err error
+		supportedFeatures, err = fetchSupportedFeatures(options.Client, options.GatewayClassName)
+		if err != nil {
+			return nil, fmt.Errorf("Cannot infer supported features: %w", err)
+		}
+		isInferred = true
+	}
+
+	// If features were not inferred from Status, it's a GWC issue.
+	if isInferred && supportedFeatures.Len() == 0 {
+		return nil, fmt.Errorf("no supported features were determined for test suite")
 	}
 
 	config.SetupTimeoutConfig(&options.TimeoutConfig)
@@ -224,19 +240,6 @@ func NewConformanceTestSuite(options ConformanceOptions) (*ConformanceTestSuite,
 		mode = options.Mode
 	}
 
-	// test suite callers can potentially just run all tests by saying they
-	// cover all features, if they don't they'll need to have provided a
-	// conformance profile or at least some specific features they support.
-	if options.EnableAllSupportedFeatures {
-		options.SupportedFeatures = features.SetsToNamesSet(features.AllFeatures)
-	} else if options.SupportedFeatures == nil {
-		options.SupportedFeatures = sets.New[features.FeatureName]()
-	}
-
-	for feature := range options.ExemptFeatures {
-		options.SupportedFeatures.Delete(feature)
-	}
-
 	suite := &ConformanceTestSuite{
 		Client:           options.Client,
 		ClientOptions:    options.ClientOptions,
@@ -254,7 +257,7 @@ func NewConformanceTestSuite(options ConformanceOptions) (*ConformanceTestSuite,
 			NamespaceAnnotations: options.NamespaceAnnotations,
 			AddressType:          options.AddressType,
 		},
-		SupportedFeatures:           options.SupportedFeatures,
+		SupportedFeatures:           supportedFeatures,
 		TimeoutConfig:               options.TimeoutConfig,
 		SkipTests:                   sets.New(options.SkipTests...),
 		RunTest:                     options.RunTest,
@@ -270,6 +273,7 @@ func NewConformanceTestSuite(options ConformanceOptions) (*ConformanceTestSuite,
 		mode:                        mode,
 		apiVersion:                  apiVersion,
 		apiChannel:                  apiChannel,
+		isInferredSupportedFeatures: isInferred,
 		Hook:                        options.Hook,
 	}
 
@@ -288,12 +292,12 @@ func NewConformanceTestSuite(options ConformanceOptions) (*ConformanceTestSuite,
 		for _, f := range conformanceProfile.ExtendedFeatures.UnsortedList() {
 			if options.SupportedFeatures.Has(f) {
 				if suite.extendedSupportedFeatures[conformanceProfileName] == nil {
-					suite.extendedSupportedFeatures[conformanceProfileName] = sets.New[features.FeatureName]()
+					suite.extendedSupportedFeatures[conformanceProfileName] = FeaturesSet{}
 				}
 				suite.extendedSupportedFeatures[conformanceProfileName].Insert(f)
 			} else {
 				if suite.extendedUnsupportedFeatures[conformanceProfileName] == nil {
-					suite.extendedUnsupportedFeatures[conformanceProfileName] = sets.New[features.FeatureName]()
+					suite.extendedUnsupportedFeatures[conformanceProfileName] = FeaturesSet{}
 				}
 				suite.extendedUnsupportedFeatures[conformanceProfileName].Insert(f)
 			}
@@ -390,6 +394,10 @@ func (suite *ConformanceTestSuite) Setup(t *testing.T, tests []ConformanceTest)
 	}
 }
 
+func (suite *ConformanceTestSuite) IsInferredSupportedFeatures() bool {
+	return suite.isInferredSupportedFeatures
+}
+
 func (suite *ConformanceTestSuite) setClientsetForTest(test ConformanceTest) error {
 	featureNames := []string{}
 	for _, v := range test.Features {
@@ -544,6 +552,7 @@ func (suite *ConformanceTestSuite) Report() (*confv1.ConformanceReport, error) {
 		GatewayAPIChannel:         suite.apiChannel,
 		ProfileReports:            profileReports.list(),
 		SucceededProvisionalTests: succeededProvisionalTests,
+		InferredSupportedFeatures: suite.IsInferredSupportedFeatures(),
 	}, nil
 }
 
@@ -573,6 +582,39 @@ func ParseConformanceProfiles(p string) sets.Set[ConformanceProfileName] {
 	return res
 }
 
+func fetchSupportedFeatures(client client.Client, gatewayClassName string) (FeaturesSet, error) {
+	if gatewayClassName == "" {
+		return nil, fmt.Errorf("GatewayClass name must be provided to fetch supported features")
+	}
+	gwc := &gatewayv1.GatewayClass{}
+	err := client.Get(context.TODO(), types.NamespacedName{Name: gatewayClassName}, gwc)
+	if err != nil {
+		return nil, fmt.Errorf("fetchSupportedFeatures(): %w", err)
+	}
+
+	fs := FeaturesSet{}
+	for _, feature := range gwc.Status.SupportedFeatures {
+		fs.Insert(features.FeatureName(feature.Name))
+	}
+	fmt.Printf("Supported features for GatewayClass %s: %v\n", gatewayClassName, fs.UnsortedList())
+	return fs, nil
+}
+
+// shouldInferSupportedFeatures checks if any flags were supplied for manually
+// picking what to test. Inferred supported features are only used when no flags
+// are set.
+func shouldInferSupportedFeatures(opts *ConformanceOptions) bool {
+	if opts == nil {
+		return false
+	}
+	return !opts.EnableAllSupportedFeatures &&
+		opts.SupportedFeatures.Len() == 0 &&
+		opts.ExemptFeatures.Len() == 0 &&
+		opts.ConformanceProfiles.Len() == 0 &&
+		len(opts.SkipTests) == 0 &&
+		opts.RunTest == ""
+}
+
 // getAPIVersionAndChannel iterates over all the crds installed in the cluster and check the version and channel annotations.
 // In case the annotations are not found or there are crds with different versions or channels, an error is returned.
 func getAPIVersionAndChannel(crds []apiextensionsv1.CustomResourceDefinition) (version string, channel string, err error) {
diff --git a/geps/gep-1324/index.md b/geps/gep-1324/index.md
index a80d6c86..5384bece 100644
--- a/geps/gep-1324/index.md
+++ b/geps/gep-1324/index.md
@@ -33,7 +33,7 @@ Gateway API represents the next generation of traffic routing APIs in Kubernetes
 
 ## Versioning
 
-Features or other modifications to the Gateway API spec that fall under this GEP will be subject to the same [versioning guidelines](../../concepts/versioning.md#graduation-criteria) as the rest of the Gateway API. For example, to move changes concerning a beta feature (e.g. HTTPRoute) from experimental to standard, all of the [beta criteria](../../concepts/versioning.md#experimental-standard) must be met (e.g. implemented by several implementations).
+Features or other modifications to the Gateway API spec that fall under this GEP will be subject to the same [versioning guidelines](../../concepts/versioning.md#graduation-criteria) as the rest of the Gateway API. For example, to move changes concerning a beta feature (e.g. HTTPRoute) from experimental to standard, all of the [graduation criteria](../../concepts/versioning.md#graduation-criteria) must be met (e.g. implemented by several implementations).
 
 ## Use-Cases
 
diff --git a/geps/gep-1619/index.md b/geps/gep-1619/index.md
index 04451eb9..1abed574 100644
--- a/geps/gep-1619/index.md
+++ b/geps/gep-1619/index.md
@@ -21,7 +21,7 @@ Before this GEP graduates to Implementable, we must fulfill the following criter
     - **Answer**: Yes. We adjusted the API to use `BackendLBPolicy`. See [API](#api) for more details.
  2. Should we leave room for configuring different forms of Session Persistence?
     If so, what would that look like?
-    - **Answer**: Yes. See the [BackendLBPolicy API](#BackendLBPolicy-api) and [API Granularity](#api-granularity)
+    - **Answer**: Yes. See the [BackendLBPolicy API](#backendlbpolicy-api) and [API Granularity](#api-granularity)
       sections for more details.
  3. What name appropriately describe the API responsible for configuring load-balancing options for backend traffic?
     - **Answer**: We decided on `BackendLBPolicy` since it is aligned with `BackendTLSPolicy`, describes configuration
@@ -668,7 +668,7 @@ functionality of their applications.
 
 ### Prior Art
 
-Referring to our [Implementations](#Implementations) table on session persistence, the majority of Gateway API
+Referring to our [Implementations](#implementations) table on session persistence, the majority of Gateway API
 implementations designed session persistence in their APIs to be attached to a service or backends. This should be
 considered cautiously, as making associations to Gateway API's notion of Gateway, Route, and Service to other
 implementation's objects is hard to directly translate. The idea of a route in Gateway API is often not the same as a
diff --git a/geps/gep-1686/index.md b/geps/gep-1686/index.md
index e986ee61..50e6e7a7 100644
--- a/geps/gep-1686/index.md
+++ b/geps/gep-1686/index.md
@@ -16,7 +16,7 @@ This testing plan specifies a new set of tests to define a "Mesh" [conformance p
 ## Focus
 
 Currently the GAMMA spec consists of two Gateway API GEPs [defining terminology and goals of Gateway API for service meshes](../gep-1324/index.md)
-and specifically [how route resources work in a service mesh context](/geps/gep-1426/).
+and specifically [how route resources work in a service mesh context](../gep-1294/index.md).
 The goal of the initial conformance testing is to check the essential behavior as defined by GEP-1426, as it differs from the wider Gateway API spec. This GEP focuses on using a `Service` object as an `xRoute` `parentRef` to control how the GAMMA implementation directs traffic to the endpoints specified by the `Services` in `backendRefs` and how the traffic is filtered and modified.
 
 ## Conformance Profile
diff --git a/geps/gep-1709/index.md b/geps/gep-1709/index.md
index b4e29acc..b370805f 100644
--- a/geps/gep-1709/index.md
+++ b/geps/gep-1709/index.md
@@ -69,7 +69,7 @@ steps:
 
 1. select a [profile](#profiles)
 2. [integrate](#integration) tests in the downstream project
-3. [report results and get certified](#certification)
+3. [report results][#reporting-process] and get certified][#certification-process]
 
 The goal is to make selecting a conformance profile as simple and automatic of a
 process as feasible and support both the existing command line integration
@@ -164,7 +164,7 @@ for i := 0; i < len(tests.ConformanceTests); i++ {
 > but when used in conjunction with `Profile` this will result in a report that
 > the profile is not valid for reporting. Implementations in this state may be
 > able to report themselves as "in progress", see the
-> [certification section](#certification) for details.
+> [certification section](#certification-process) for details.
 
 Alternatively for an `Extended` conformance profile where not all of the
 features are implemented (as described in the [profiles](#profiles) section
@@ -234,7 +234,7 @@ support, or opt-out of the features you _don't_ support using
 `UnsupportedFeatures`.
 
 Once an implementation has integrated with the conformance test suite, they can
-move on to [certification](#certification) to report the results.
+move on to [certification](#certification-process) to report the results.
 
 [go-test]:https://go.dev/doc/tutorial/add-a-test
 [go]:https://go.dev
diff --git a/geps/gep-1867/index.md b/geps/gep-1867/index.md
index cf664362..eba4f6e2 100644
--- a/geps/gep-1867/index.md
+++ b/geps/gep-1867/index.md
@@ -36,7 +36,7 @@ This has been previously discussed in [this issue](https://github.com/kubernetes
 
 As a cluster scoped resource, `GatewayClass` does not meet this requirement.
 This restricts customization use cases to either a few pre-provisioned classes by the admin, or running in an environment where the "Infrastructure Provider" and "Cluster Operator" are the same roles.
-The distinction between these roles is explicitly called out on the [homepage](../../index.md#what-is-the-gateway-api).
+The distinction between these roles is explicitly called out on the [homepage](../../index.md#personas).
 
 ### Custom Resource
 
diff --git a/geps/gep-1897/index.md b/geps/gep-1897/index.md
index 9f2a9918..3203d34d 100644
--- a/geps/gep-1897/index.md
+++ b/geps/gep-1897/index.md
@@ -405,8 +405,6 @@ the implementation would be required to fully implement the policy or mark the b
 
 [GEP-713: Metaresources and PolicyAttachment](../gep-713/index.md)
 
-[Policy Attachment](../../reference/policy-attachment.md#direct-policy-attachment)
-
 [Gateway API TLS](../../guides/tls.md)
 
 [SIG-NET Gateway API: TLS to the K8s.Service/Backend](https://docs.google.com/document/d/1RTYh2brg_vLX9o3pTcrWxtZSsf8Y5NQvIG52lpFcZlo)
diff --git a/geps/gep-2722/index.md b/geps/gep-2722/index.md
index 135e2c76..fc6a609d 100644
--- a/geps/gep-2722/index.md
+++ b/geps/gep-2722/index.md
@@ -387,7 +387,7 @@ distribution mechanisms will be provided:
   for visualizing data and presenting information in a visually appealing
   manner.
 * Evaluate how gwctl can be extended to support [Mesh use
-  cases](/concepts/gamma/#how-the-gateway-api-works-for-service-mesh)
+  cases](../../mesh/index.md)
 
 ## References
 
diff --git a/geps/gep-3779/index.md b/geps/gep-3779/index.md
new file mode 100644
index 00000000..49464b16
--- /dev/null
+++ b/geps/gep-3779/index.md
@@ -0,0 +1,266 @@
+# GEP-3779: Identity Based Authz for East-West Traffic
+
+* Issue: [#3779](https://github.com/kubernetes-sigs/gateway-api/issues/3779)
+* Status: Provisional
+
+(See [status definitions](../overview.md#gep-states).)
+
+
+## TLDR
+
+Provide a method for configuring Gateway API Mesh implementations to enforce east-west identity-based Authorization controls. At the time of writing this we leave Authentication for specific implementation and outside of this proposal scope.
+
+
+## Goals
+
+(Using the [Gateway API Personas](../../concepts/roles-and-personas.md))
+
+* A way for Ana the Application Developer to configure a Gateway API for Mesh implementation to enforce authorization policy that **allows** or **denies** identity or multiple identities to talk with some set (could be namespace or more granualr) of the workloads she controls.
+
+* A way for both Ana and Chihiro to restrict the scope of the policies they deploy to specific ports.
+
+## TBD Goals
+
+* A way for Chihiro, the Cluster Admin, to configure a Gateway API for Mesh implementation to enforce non-overridable cluster-wide, authorization policies that **allows** or **denies** identity or multiple identities to talk with some set of the workloads in the cluster.
+
+* A way for Chihiro, the Cluster Admin, to configure a Gateway API for Mesh implementation to enforce default, overridable, cluster-wide, authorization policies that **allows** or **denies** identity or multiple identities to talk with some set of the workloads in the cluster.
+
+## Non-Goals
+
+* Support identity based authorization for north-south traffic or define the composition with this API.
+
+## Deferred Goals
+
+* (Potentially) Support enforcement on attributes beyond identities and ports.
+
+
+## Introduction
+
+Authorization is positioned as one of core mesh values. Every mesh supports some kind of east/west authorization between the workloads it controls.
+
+Kubernetes core provides NetworkPolicies as one way to do it. Network Policies however falls short in many ways including:
+
+* Network policies leverage labels as identities.
+  * Labels are mutable at runtime. This opens a path for escalating privileges
+  * Most implementations of network policies translate labels to IPs, this involves an eventual consistency nature which can and has lea to over permissiveness in the past.
+
+* Scale. Network Policies are enforced using IPs (different selectors in the APIs get translated to IPs). This does not scale well with large clusters or beyond a single cluster
+
+An identity-based authorization API is essential because it provides a structured way to control authorization between identities within the cluster.
+
+
+### State of the World
+
+
+| Aspect | Istio | Linkerd | Cilium |
+| ----- | ----- | ----- | ----- |
+| **Policy CRDs** | `AuthorizationPolicy` (APIs `security.istio.io/v1`) | `AuthorizationPolicy` (CRD `policy.linkerd.io/v1alpha1`), plus supporting CRDs (`Server`, `HTTPRoute`, `MeshTLSAuthentication`) | `CiliumNetworkPolicy` and `CiliumClusterwideNetworkPolicy` (superset of K8s NetworkPolicy) |
+| **Identity model** | Identities derived from mTLS peer certificates (bound to SA): <ul><li>SPIFFE-like principal `<trust-domain>/ns/<namespace>/sa/<serviceaccount>`. </li> <li>ServiceAccount name </li> <li>Namespaces</li></ul></br> identity within JWT derived from `request.auth.principal`<br/><br/>IPBlocks and x-forwarded-for ipBlocks | Identities derived from mTLS peer certificates (bound to SA trust domain `identity.linkerd.cluster.local`. Policies reference service accounts or explicit mesh identities (e.g. `webapp.identity.linkerd.cluster.local`). <br/><br/>Policies use `requiredAuthenticationRefs` to reference the entities who get authorization. This is a list of targetRefs and it can include: <ul><li>ServiceAccounts</li> <li>`MeshTLSAuthentication` - which represents a set of mesh identities either with a mesh identities strings or reference to serviceAccounts</li> <li>`NetworkAuthentication` - represents sets of IPs or subnets.</li></ul>  |Cilium service mesh can leverage SPIFFE identities in certs that are used for handshake. These SPIFFEE identities are mapped to CiliumIdentities. You can read more about cilium identities in [CiliumIdentity](#CiliumIdentity). <br/><br/>Policies target abstractions like service accounts in the form of labels, pod labels, namespace label, node selectors, CIDR blocks and Cilium predefined [entities](https://docs.cilium.io/en/stable/security/policy/language/#entities-based). All policy targeting is coalesced by Cilium into one or more Cilium Identities for translation into the BPF datapath|
+| **Enforcement** | For Istio with sidecars - a proxy on each pod. For ambient, ztunnel node agent enforces mTLS based L4 authorization, L7 authorization is being enforced in waypoints if any. <br/><br/> Istio supports ALLOW, DENY, CUSTOM (often used for external authorization), and AUDIT. DENY policies in istio's context are used to enforce higher priority deny policies. The allow semantics is that whatever is not allowed explicitly (and assuming there is any policy for the same match) is implicitly denied  | Linkerd data-plane proxy (injected into each pod). The proxy enforces policies via mTLS identity checks. <br/><br/> Linkerd supports AUDIT and ALLOW. There is not DENY policies, whats not allowed (and assuming there is any policy for the same match) is implicitly denied. | For L3/4 Ingress Rules, CiliumNetworkPolicy enforcement - an eBPF-based datapath in the Linux kernel on the destination node. If L7 http rules are specified, the packet is redirected for a node-local envoy for further enforcement.<br/><br/>Cilium supports ALLOW and DENY semantics - all policies generate audit logs. <br/><br/>Cilium service mesh also offers a kind of AuthN where a Cilium agent on the src node validates a workloads SPIFFE identity by talking to another agent on the destination node, performing the initial TLS handshake to do authentication.|
+| **Request Match criteria** | Policies can target a group of pods using label selector, a Gateway/Service (this means targeting a waypoint proxy) or a GatewayClass - meaning all the gateways created from this class.  Policies without a label selector in a namespace implies the whole namespace is targeted. <br/><br/> Fine-grained L7 and L4 matching: HTTP/gRPC methods, paths, headers, ports, SNI, etc.Policies use logical OR over rules. <br/><br/>All match criterias are inline in the policy. See https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-To and https://istio.io/latest/docs/reference/config/security/authorization-policy/#Rule-when | Policies can target: <ul><li>A `Server` which describes a set of pods (using fancy label match expressions), and a single port on those pods.</li> <li>A user can optionally restrict the authorization to a smaller subset of the traffic by targeting an HTTPRoute. (TODO: any plans to support sectionNames?)</li> <li> A namespace - this indicates that the policy applies to all traffic to all Servers and HTTPRoutes defined in the namespace.</li></ul> Note: We leave `ServerAuthorization` outside the scope as it planned to be deprecated (per linkerd website)  | Policies can target groups of pods using label selector (`endpointSelector`), or by node-labels (`nodeSelector`). Cilium supports L7 via built-in HTTP parsing: rules can match HTTP methods, paths, etc. For example, a CiliumNetworkPolicy can allow only specific HTTP methods/paths on a port. |
+| **Default policies and admin policies** | If **no** ALLOW policy matches, traffic is **allowed** by default. You can deploy an overridable - default deny by default by deploying an **allow-nothing** policy in either the namespace or istio-system <br/><br/>AuthorizationPolicies in the `istio-system` namespace apply to the whole mesh and take precedence. These are not overridable by namespace-level policies.  | Default inbound policy can be set at install time using `proxy.defaultInboundPolicy`. Supported values are: <ul><li>`all-unauthenticated:` allow all traffic. This is the default.</li>  <li>`all-authenticated:` allow traffic from meshed clients in the same or from a different cluster (with multi-cluster).</li>  <li>`cluster-authenticated:` allow traffic from meshed clients in the same cluster.</li>  <li>`cluster-unauthenticated:` allow traffic from both meshed and non-meshed clients in the same cluster.</li>  <li>`deny:` all traffic are denied. </li> <li>`audit:` Same as all-unauthenticated but requests get flagged in logs and metrics.</li> </ul> <br/>Users can override the default policies for namespaces/pods or by setting the [config.linkerd.io/default-inbound-policy](http://config.linkerd.io/default-inbound-policy) annotation There is no support for admin, non overridable policies. | Follows Kubernetes NetworkPolicy semantics by default: if no `CiliumNetworkPolicy` allows the traffic, it is allowed (no implicit deny). Once at least one `CiliumNetworkPolicy` or `CiliumClusterwideNetworkPolicy` allows some traffic, all other traffic is implicitly denied.
+<br/><br/> Operators must apply explicit deny rules or “default-deny” policies to block traffic in the absence of allow rules. <br/><br/> `CiliumClusterwideNetworkPolicy` exists for whole-cluster enforcement.)|
+
+
+Every mesh vendor has their own API of such authorization. Below we describe brief UX for different implementations:
+
+#### Istio
+For the full spec and sematics of Istio AuthorizationPolicy: [Istio authorization policy docs](https://istio.io/latest/docs/reference/config/security/authorization-policy/)
+
+Istio's AuthorizationPolicy can enforce access control by specifying allowed istio-formatted identities using the `source.principals` field, which matches authenticated service account identities via mTLS. You can also use other source constructs which are described in the table above and in https://istio.io/latest/docs/reference/config/security/authorization-policy/#Source.
+
+```
+apiVersion: security.istio.io/v1beta1
+kind: AuthorizationPolicy
+metadata:
+  name: allow-sleep
+  namespace: default
+spec:
+  selector:
+    matchLabels:
+      app: httpbin  # The policy applies to pods with this label
+  action: ALLOW
+  rules:
+  - from:
+    - source:
+        principals: ["cluster.local/ns/default/sa/sleep"]
+```
+
+OR targeting a gateway for example.
+
+```
+apiVersion: security.istio.io/v1beta1
+kind: AuthorizationPolicy
+metadata:
+  name: allow-sleep
+  namespace: default
+spec:
+  targetRefs:
+  - name: waypoint
+    kind: Gateway # note: supported target Refs are Gateway, GatewayClass, Service, and ServiceEntry
+    group: gateway.networking.k8s.io
+  action: ALLOW
+  rules:
+  - from:
+    - source:
+        principals: ["cluster.local/ns/default/sa/sleep"]
+```
+#### Linkerd
+
+For the full spec and sematics of Linkerd AuthorizationPolicy: [Linkerd authorization policy docs](https://linkerd.io/2-edge/reference/authorization-policy/)
+
+In Linkerd, identity-based authorization is enforced using AuthorizationPolicy and MeshTLSAuthentication, where MeshTLSAuthentication specifies allowed ServiceAccounts or mTLS identities (e.g., sleep.default.serviceaccount.identity.linkerd.cluster.local), ensuring that only authenticated workloads can access a resource.
+
+Linkerd Policy can by applied to two different targets.
+
+##### Pod Labels with Server Resource
+
+```
+apiVersion: policy.linkerd.io/v1beta1
+kind: Server
+metadata:
+  namespace: default
+  name: httpbin-server
+spec:
+  podSelector:
+    matchLabels:
+      app: httpbin
+  port: 8080
+  proxyProtocol: HTTP/2
+
+----
+apiVersion: policy.linkerd.io/v1beta1
+kind: MeshTLSAuthentication
+metadata:
+  name: sleep-authn
+  namespace: default
+spec:
+  identities:
+    - sleep.default.serviceaccount.identity.linkerd.cluster.local
+----
+
+apiVersion: policy.linkerd.io/v1beta1
+kind: AuthorizationPolicy
+metadata:
+  name: allow-sleep
+  namespace: default
+spec:
+  targetRef:
+    group: policy.linkerd.io
+    kind: Server
+    name: httpbin-server
+  requiredAuthenticationRefs:
+    - name: sleep-authn
+      kind: MeshTLSAuthentication
+      group: policy.linkerd.io/v1beta1
+
+---
+```
+
+##### HTTPRoutes
+
+```
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: httpbin-route
+  namespace: default
+spec:
+  parentRefs:
+    - name: httpbin
+      kind: Service
+  rules:
+    - matches:
+        - path:
+            type: PathPrefix
+            value: /
+      backendRefs:
+        - name: httpbin
+          port: 80
+
+-----
+
+apiVersion: policy.linkerd.io/v1beta1
+kind: MeshTLSAuthentication
+metadata:
+  name: sleep-authn
+  namespace: default
+spec:
+  identities:
+    - sleep.default.serviceaccount.identity.linkerd.cluster.local
+-----
+
+apiVersion: policy.linkerd.io/v1beta1
+kind: AuthorizationPolicy
+metadata:
+  name: allow-sleep-http
+  namespace: default
+spec:
+  targetRef:
+    group: gateway.networking.k8s.io
+    kind: HTTPRoute
+    name: httpbin-route
+  requiredAuthenticationRefs:
+    - name: sleep-authn
+      kind: MeshTLSAuthentication
+      group: policy.linkerd.io/v1beta1
+---
+```
+
+
+#### Cilium
+
+For the full spec and sematics of CiliumNetworkPolicy: https://docs.cilium.io/en/stable/network/kubernetes/policy/#ciliumnetworkpolicy & https://docs.cilium.io/en/stable/network/servicemesh/gateway-api/gateway-api/#cilium-s-ingress-config-and-ciliumnetworkpolicy
+
+Beyond what's explained in the table above, Cilium also automatically labels each pod with its associated service account using the label io.cilium.k8s.policy.serviceaccount. This label can be used in CiliumNetworkPolicy to enforce identity-based access controls using [ServiceAccounts Based Identities](https://docs.cilium.io/en/latest/security/policy/kubernetes/#serviceaccounts) within CiliumNetworkPolicy;
+
+See below for example.
+
+```
+apiVersion: "cilium.io/v2"
+kind: CiliumNetworkPolicy
+metadata:
+  name: "k8s-svc-account-policy"
+spec:
+  endpointSelector:
+    matchLabels:
+      io.cilium.k8s.policy.serviceaccount: httpbin
+  ingress:
+  - fromEndpoints:
+    - matchLabels:
+        io.cilium.k8s.policy.serviceaccount: sleep
+    toPorts:
+    - ports:
+      - port: '80'
+        protocol: TCP
+      rules:
+        http:
+        - method: GET
+          path: "/"
+```
+
+
+##### CiliumIdentity
+Cilium has the concept of CiliumIdentity. Pods are assigned identities derived from their Kubernetes labels (namespace, app labels, etc.). Cilium’s policy matches based on these label-derived identities. The CiliumIdentity implementation maps an integer to a group of IP addresses (the pod IPs associated with a group of pods). This “integer” and its mapping to pod IP addresses represents the core identity primitive in Cilium.  
+
+More on https://docs.cilium.io/en/stable/internals/security-identities/ & https://docs.cilium.io/en/stable/security/network/identity/
+
+
+
+## API
+
+
+
+## Conformance Details
+
+
+#### Feature Names
+
+
+### Conformance tests 
+
+
+## Alternatives
+
+
+## References
\ No newline at end of file
diff --git a/geps/gep-3779/metadata.yaml b/geps/gep-3779/metadata.yaml
new file mode 100644
index 00000000..3c5b9af7
--- /dev/null
+++ b/geps/gep-3779/metadata.yaml
@@ -0,0 +1,19 @@
+apiVersion: internal.gateway.networking.k8s.io/v1alpha1
+kind: GEPDetails
+number: 3779
+name: Identity Based Authz for east-west traffic
+status: Provisional
+# Any authors who contribute to the GEP in any way should be listed here using
+# their GitHub handle.
+authors:
+  - liorlieberman
+  - aryan16
+# 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.
+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-3792/index.md b/geps/gep-3792/index.md
new file mode 100644
index 00000000..b0c5d80b
--- /dev/null
+++ b/geps/gep-3792/index.md
@@ -0,0 +1,264 @@
+# GEP-3792: Out-of-Cluster Gateways
+
+* Issue: [#3792](https://github.com/kubernetes-sigs/gateway-api/issues/3792)
+* Status: Provisional
+
+(See [status definitions](../overview.md#gep-states).)
+
+## User Story
+
+**[Chihiro] and [Ian] want a way for out-of-cluster Gateways to be able to
+usefully participate in a GAMMA-compliant in-cluster service mesh.**
+
+Historically, API gateways and ingress controllers have often been implemented
+using a Service of type LoadBalancer fronting a Kubernetes pod running a
+proxy. This is simple to reason about, easy to manage for sidecar meshes, and
+will presumably be an important implementation mechanism for the foreseeable
+future. Some cloud providers, though, are moving the proxy outside of the
+cluster, for various reasons which are out of the scope of this GEP. Chihiro
+and Ian want to be able to use these out-of-cluster proxies effectively and
+safely, though they recognize that this may require additional configuration.
+
+[Chihiro]: https://https//gateway-api.sigs.k8s.io/concepts/roles-and-personas/#chihiro
+[Ian]: https://https//gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ian
+
+### Nomenclature and Background
+
+In this GEP:
+
+1. We will use _out-of-cluster Gateway_ (OCG) to refer to a conformant
+   implementation of Gateway API's `GATEWAY` profile that's running outside of
+   the cluster. This would most commonly be a managed implementation from a
+   cloud provider, but of course there are many other possibilities -- and in
+   fact it's worth noting that anything we define here to support OCGs could
+   also be used by workloads that run in-cluster but which, for whatever
+   reason, can't be brought into the mesh in the mesh's usual way.
+
+2. We'll also distinguish between _mTLS meshes_, which rely on standard mTLS
+   for secure communication (authentication, encryption, and integrity
+   checking) between workloads, and _non-mTLS meshes_, which do anything else.
+   We'll focus on mTLS meshes in this GEP; this isn't because of a desire to
+   exclude non-mTLS meshes, but because we'll have enough trouble just
+   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.
+
+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
+   primarily be concerned with _workload authentication_, in which the
+   principal is a workload, as opposed to _user authentication_, in which the
+   principal is the human on whose behalf a piece of technology is acting. We
+   expect that the OCG will handle user auth, but of course meshed workloads
+   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).
+
+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.
+
+   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
+
+- Allow Chihiro and Ian to configure an OCG and a mesh such that the OCG can
+  usefully participate in the mesh, including:
+
+    - The OCG must be able to securely communicate with meshed workloads in
+      the cluster, where "securely communicate" includes encryption,
+      authentication, and integrity checking.
+
+    - The OCG must have a proper identity within the mesh, so that the mesh
+      can apply authorization policy to requests from the OCG.
+
+    - Whatever credentials the OCG and the mesh use to authenticate each other
+      must be able to be properly maintained over time (for example, if they
+      use mTLS, certificates will need rotation over time).
+
+    - The OCG must be able to distinguish meshed workloads from non-meshed
+      workloads, so that it can communicate appropriately with each.
+
+- Allow Ana to develop and operate meshed applications without needing to know
+  whether the Gateway she's using is an OCG or an in-cluster Gateway.
+
+- Define a basic set of requirements for OCGs and meshes that want to
+  interoperate with each other (for example, the OCG and the mesh will likely
+  need to agree on how workload authentication principals are represented).
+
+- Define how responsibility is shared between the OCG and the mesh for
+  outbound behaviors applied to requests leaving the OCG. (Note that "the OCG
+  has complete responsibility and authority over outbound behaviors for
+  requests leaving the OCG" is very much a valid definition.)
+
+## Non-Goals
+
+- Support multicluster operations. It may be the case that functional
+  multicluster (with, e.g., a single OCG fronting multiple clusters) ends up
+  falling out of this GEP, but it is not a goal.
+
+- Support meshes interoperating with each other. It's possible that this GEP
+  will lay a lot of groundwork in that direction, but it is not a goal.
+
+- Support non-mTLS meshes in Gateway API 1.4. We'll make every effort not to
+  rule out non-mTLS meshes, but since starting with the mTLS meshes should
+  tackle a large chunk of the industry with a single solution, that will be
+  the initial focus.
+
+- Solve the problem of extending a mesh to cover non-Kubernetes workloads (AKA
+  _mesh expansion_). In many ways, mesh expansion is adjacent to the OCG
+  situation, but the where the OCG is aware of the cluster and mesh, mesh
+  expansion deals with a non-Kubernetes workload that is largely not aware of
+  either.
+
+- Solve the problem of how to support an OCG doing mTLS directly to a
+  _non_-meshed workload (AKA the _backend TLS problem_). Backend TLS to
+  non-meshed workloads is also adjacent to the OCG situation, but its
+  configuration has different needs: backends terminating TLS on their own are
+  likely to need per-workload configuration of certificates, cipher suites,
+  etc., where the mesh as a whole should share a single configuration.
+
+- Prevent the OCG API from being used by an in-cluster workload. We're not
+  going to make in-cluster workloads a primary use case for this GEP, but
+  neither are we disallowing them.
+
+## Overview
+
+Making an OCG work with an in-cluster mesh at the most basic level doesn't
+really require any special effort. As long as the OCG has IP connectivity to
+pods in the cluster, and the mesh is configured with permissive security, the
+OCG can simply forward traffic from clients directly to meshed pods, and
+things will "function" in that requests from clients, through the OCG, can be
+handled by workloads in the cluster.
+
+Of course, this sort of non-integration has obvious and terrible security
+implications, since the traffic between the OCG and the application pods in
+the cluster will be cleartext in the scenario above. The lack of encryption is
+awful in its own right, but the fact that any mTLS mesh uses mTLS for
+_authentication_ also means that the mesh loses any way to enforce
+authorization policy around the OCG. Combined, these items amount to a major
+problem.
+
+An additional concern is that the OCG needs to be able to implement features
+(e.g. sticky sessions) which require it to speak directly to endpoint IPs,
+which can limit what the mesh will be able to do. This is likely a more minor
+concern since a conformant OCG should itself be able to provide advanced
+functionality; however, at minimum it can create some friction in
+configuration.
+
+### The Problems
+
+To allow the OCG to _usefully_ participate in the mesh, we need to solve at
+least four significant problems. Thankfully, these are mostly problems for
+Chihiro -- if we do our jobs correctly, Ana will never need to know.
+
+#### 1. The Trust Problem
+
+The _trust problem_ is fairly straightforward to articulate: the OCG and the
+mesh both need access to whatever information will allow each of them to trust
+the other.
+
+In the case of mTLS meshes, we are helped by the fact that basically every OCG
+candidate already speaks mTLS, so the trust problem becomes "only" one of
+setting things up for the OCG and the mesh to each include the other's CA
+certificate in their trust bundle. (They may be using the same CA certificate,
+but we shouldn't rely on that.)
+
+In the case of non-mTLS meshes, the trust problem is more complex; this is the
+major reason that this GEP is focused on mTLS meshes.
+
+#### 2. The Protocol Problem
+
+The _protocol problem_ is that the data-plane elements of the mesh may assume
+that they'll always be talking only to other mesh data-plane elements, which
+the OCG will not be. If the mesh data-plane elements use a specific protocol,
+then either the OCG will need to speak that protocol, or the mesh will need to
+relax its requirements (perhaps on a separate port?) to accept requests
+directly from the OCG.
+
+For example, Linkerd and Istio Legacy both use standard mTLS for
+proxy-to-proxy communication -- however, both also use ALPN to negotiate
+custom (and distinct!) "application" protocols during mTLS negotiation, and
+depending on the negotiated protocol, both can require the sending proxy to
+send additional information after mTLS is established, before any client data
+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
+
+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
+namespaces not meshed, especially during migrations). The _discovery problem_
+here is that the OCG needs to be know which workloads are meshed, so that it
+can choose appropriate communication methods for them.
+
+#### 4. The Outbound Behavior Problem
+
+The OCG will need to speak directly to endpoints in the cluster, as described
+above. This will prevent most meshes from being able to tell which service was
+originally requested, which makes it impossible for the mesh to apply outbound
+behaviors. This is the _outbound behavior problem_: it implies that either the
+OCG must be responsible for outbound behaviors for requests leaving the OCG
+for a meshed workload, or that the OCG must supply the mesh with enough
+information about the targeted service to allow the mesh to apply those
+outbound behaviors (if that's even possible: sidecar meshes may very well
+simply not be able to do this.)
+
+This is listed last because it shouldn't be a functional problem to simply
+declare the OCG solely responsible for outbound behaviors for requests leaving
+the OCG. It is a UX problem: if a given workload needs to be used by both the
+OCG or other meshed workloads, you'll need to either provide two Routes with
+the same configuration, or you'll need to provide a single Route with multiple
+`parentRef`s.
+
+## API
+
+Most of the API work for this GEP is TBD at this point, but there are two
+important points to note:
+
+First, Gateway API has never defined a Mesh resource because, to date, it's
+never been clear what would go into it. This may be the first configuration
+item that causes us to need a Mesh resource.
+
+Second, since the API should affect only Gateway API resources, it is not a
+good candidate for policy attachment. It is likely to be much more reasonable
+to simply provide whatever extra configuration we need inline in the Gateway
+or Mesh resources.
+
+## Graduation Criteria
+
+In addition to the [general graduation
+criteria](../concepts/versioning.md#graduation-criteria), this GEP must also
+guarantee that **all four** of the problems listed above need resolutions, and
+must have implementation from at least two different Gateways and two
+different meshes.
+
+### Gateway for Ingress (North/South)
+
+### Gateway For Mesh (East/West)
+
+## Conformance Details
+
+#### Feature Names
+
+This GEP will use the feature name `MeshOffClusterGateway`, under the
+assumption that we will indeed need a Mesh resource.
+
+### Conformance tests
+
+## Alternatives
+
+## References
diff --git a/geps/gep-3792/metadata.yaml b/geps/gep-3792/metadata.yaml
new file mode 100644
index 00000000..4478b32b
--- /dev/null
+++ b/geps/gep-3792/metadata.yaml
@@ -0,0 +1,33 @@
+apiVersion: internal.gateway.networking.k8s.io/v1alpha1
+kind: GEPDetails
+number: 3792
+name: Out-of-Cluster Gateways
+status: Provisional
+# Any authors who contribute to the GEP in any way should be listed here using
+# their GitHub handle.
+authors:
+  - kflynn
+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-3793/index.md b/geps/gep-3793/index.md
new file mode 100644
index 00000000..0c8ba3e6
--- /dev/null
+++ b/geps/gep-3793/index.md
@@ -0,0 +1,217 @@
+# GEP-3793: Default Gateways
+
+* Issue: [#3793](https://github.com/kubernetes-sigs/gateway-api/issues/3793)
+* Status: Provisional
+
+(See [status definitions](../overview.md#gep-states).)
+
+## User Story
+
+**[Ana] wants a concept of a default Gateway.**
+
+Gateway API currently requires every north/south Route object to explicitly
+specify its parent Gateway. This is helpful in that it removes ambiguity, but
+it's less helpful in that [Ana] is stuck constantly explicitly configuring a
+thing that she probably doesn't care much about: in a great many cases, Ana
+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.
+
+[Ana]: https://https//gateway-api.sigs.k8s.io/concepts/roles-and-personas/#ana
+
+## Goals
+
+- Give Ana a way to use Gateway API without having to explicitly specify a
+  Gateway for every Route, ideally without mutating Routes.
+
+- Give Ana an easy way to determine which Gateway is the default, and which of
+  her Routes are bound to it.
+
+- Continue supporting multiple Gateways in a cluster, while allowing exactly
+  one of them to be the default Gateway.
+
+- 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 choose not to provide a default Gateway.
+
+- Allow Chihiro to rename, reconfigure, or replace the 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.
+
+  - 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
+    `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.
+
+- Support easy interoperation with common CI/CD and GitOps workflows.
+
+- Define how (or if) listener and Gateway merging applies to a default
+  Gateway.
+
+## 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 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
+  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.
+
+- Allow for "default Gateway" functionality without a Gateway controller
+  installed. Just as with any other Gateway, a default Gateway requires an
+  implementation to be installed.
+
+## Overview
+
+Gateway API currently requires every north/south Route object to explicitly
+specify its parent Gateway. This is a wonderful example of a fundamental
+tension in Gateway API:
+
+- [Chihiro] and [Ian] value _explicit definition_ of everything, because it
+  makes it easier for them to reason about the system and ensure that it meets
+  the standards they set for it.
+
+- [Ana], on the other hand, values _simplicity_ and _ease of use_, because
+  she just wants to get her job done without having to think about every little
+  detail.
+
+At present, Gateway API is heavily weighted towards the point of view of
+Chihiro and Ian. This causes friction for Ana: for example, she can't write
+examples or documentation for her colleagues (or her counterparts at other
+companies) without telling them that they'll need to be sure to edit the
+Gateway name in every Route. Nor can she write a Helm chart that includes a
+Route without requiring the person using the chart to know the specific name
+for the Gateway to use.
+
+The root cause of this friction is a difference in perspective: to Chihiro and
+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.
+
+### 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.
+
+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:
+
+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.
+
+(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.)
+
+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.
+
+### Debugging and Visibility
+
+It's also critical to note that visibility is critical when debugging: if Ana
+can't tell which Gateway is being used by a given Route, then her ability to
+troubleshoot problems is _severely_ hampered. Of course, one of the major
+strengths of Gateway API is that it _does_ provide visibility into what's
+going on in the `status` stanzas of its resources: every Route already has a
+`status` showing exactly which Gateways it is bound to. Making certain that
+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.
+
+[Chihiro]: https://https//gateway-api.sigs.k8s.io/concepts/roles-and-personas/#chihiro
+[Ian]: https://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.
+
+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
+Kubernetes cluster, and then monitoring the cluster for changes. If a tool
+like Argo CD or Flux detects a change to a resource in the cluster, it will
+attempt to reconcile that change with the manifest in the Git repository --
+which means that changes to the `spec` of an HTTPRoute that are made by code
+running in the cluster, rather than by a user with a Git commit, can
+potentially trip up these tools.
+
+These tools generally ignore strict additions: if a field in `spec` is not
+present in the manifest in Git, but is added by code running in the cluster,
+the tools know to ignore it. So, for example, if `spec.parentRefs` is not
+present at all in the manifest in Git, CD tools can probably tolerate having a
+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.
+
+[discussion]: https://github.com/kubernetes-sigs/gateway-api/pull/3852#discussion_r2140117567
+
+### Gateway for Ingress (North/South)
+
+### Gateway For Mesh (East/West)
+
+## Conformance Details
+
+#### Feature Names
+
+The default-gateway feature will be named `HTTPRouteDefaultGateway` and
+`GRPCRouteDefaultGateway`. It is unlikely that an implementation would support
+one of these Route types without the other, but `GatewayDefaultGateway` does
+not seem like a good choice.
+
+### Conformance tests
+
+## 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.
+
+[default Listeners]: https://github.com/kubernetes-sigs/gateway-api/pull/3852#discussion_r2149056246
+
+## References
diff --git a/geps/gep-3793/metadata.yaml b/geps/gep-3793/metadata.yaml
new file mode 100644
index 00000000..060426f0
--- /dev/null
+++ b/geps/gep-3793/metadata.yaml
@@ -0,0 +1,33 @@
+apiVersion: internal.gateway.networking.k8s.io/v1alpha1
+kind: GEPDetails
+number: 3793
+name: Default Gateways
+status: Provisional
+# Any authors who contribute to the GEP in any way should be listed here using
+# their GitHub handle.
+authors:
+  - kflynn
+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-3798/index.md b/geps/gep-3798/index.md
new file mode 100644
index 00000000..84b4a603
--- /dev/null
+++ b/geps/gep-3798/index.md
@@ -0,0 +1,80 @@
+# GEP-3798: Client IP-Based Session Persistence
+
+* Issue: [#3798](https://github.com/kubernetes-sigs/gateway-api/issues/3798)
+* Status: Provisional
+
+(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.
+
+## TLDR
+
+### What
+ This GEP proposes the addition of Client IP-based session persistence to the Gateway API. This feature will allow Gateway API implementations to ensure that requests originating from a specific client IP address (or a subnet defined by an IP mask) are consistently routed to the same backend endpoint for a configurable duration. This aims to provide a standardized and centralized mechanism for client IP persistence across various Gateway API implementations.
+
+ As mentioned in the [GEP-1619](https://gateway-api.sigs.k8s.io/geps/gep-1619/#api), `SessionPersistence` can be applied via `BackendLBPolicy` and `RouteRule` API. Similar [edge case behaviour](https://gateway-api.sigs.k8s.io/geps/gep-1619/#edge-case-behavior) and [API Granularity](https://gateway-api.sigs.k8s.io/geps/gep-1619/#api-granularity) for ClientIP Persistence type should be applicable as well.
+
+ An important addition/difference compared to [GEP-1619](https://gateway-api.sigs.k8s.io/geps/gep-1619) is that the identity of the backend assigned to a client (or a group of clients in the same subnet) is stored on the server (load balancer / gateway) side as opposed to the client side.
+
+## Goals
+
+* Define an API extension within Gateway API to enable client IP-based session persistence.
+
+* Allow configuration of a session duration for which a client IP should stick to a backend.
+
+* Provide an optional mechanism to specify an IP mask for subnet-based persistence, allowing multiple clients from the same subnet to be routed to the same backend.
+
+* Improve portability of applications requiring client IP persistence across different Gateway API implementations.
+
+## Non-Goals
+
+This GEP does not dictate the specific algorithm or implementation details for how an individual Gateway controller maintains the client IP-to-backend mapping (e.g., in-memory, distributed cache).
+
+## Introduction
+
+### Why: The Problem This Solves
+Currently, achieving client IP-based session persistence within Kubernetes Gateway API environments often requires vendor-specific annotations or out-of-band configurations on the underlying load balancer or ingress controller. This approach has several drawbacks:
+
+* Inconsistent User Experience: Users have to learn different methods for configuring the same logical feature depending on their chosen Gateway API implementation. Configurations are not easily transferable between different Gateway API implementations, leading to vendor lock-in and increased operational overhead when migrating or using multiple controllers.
+
+* Reduced Visibility: The desired session persistence behavior is not explicitly declared within the Gateway API resources, making it harder to audit, manage, and understand the routing logic from a single source of truth.
+
+This GEP addresses these issues by providing a first-class API mechanism for client IP-based session persistence, enhancing the Gateway API's capabilities and promoting consistency and portability.
+
+### Who: Beneficiaries
+* Application Developers: Can define session persistence requirements directly in their Gateway API configurations, ensuring consistent behavior regardless of the underlying Gateway implementation. This simplifies application deployment and management for stateful workloads.
+
+* Platform Operators/Administrators: Gain a standardized way to configure and manage client IP-based session persistence across their clusters, reducing the need for custom scripts or deep knowledge of individual controller implementations. This improves operational efficiency and consistency.
+
+* Gateway API Implementers: Receive a clear specification for implementing client IP-based session persistence, fostering interoperability and reducing divergent approaches.
+
+* Users with Stateful/Legacy Applications: Applications that rely on client IP Persistence (e.g., certain legacy applications, gaming servers, or applications with in-memory session stores) will directly benefit from a reliable and configurable persistence mechanism.
+
+## API
+
+TODO: when we get to the implementation iterations, we need to consider whether we can implement this using functionality established in [GEP-1619](https://gateway-api.sigs.k8s.io/geps/gep-1619).
+
+### Conformance tests 
+
+NA
+
+## Alternatives
+
+Yet to do
+
+## References
+
+Below are references showing how ClientIP persistence is currently supported across some implementations:
+
+* [AVI](https://techdocs.broadcom.com/us/en/vmware-security-load-balancing/avi-load-balancer/avi-load-balancer/30-2/load-balancing-overview/persistence.html)
+* [Native k8s](https://kubernetes.io/docs/reference/networking/virtual-ips/#session-affinity)
+
+Below are some implementations of ClientIP persistence which allows configuring subnet Mask 
+
+* [F5](https://techdocs.f5.com/content/kb/en-us/products/big-ip_ltm/manuals/product/ltm-concepts-11-5-1/11.html#:~:text=is%20persisted%20properly.-,Source%20address%20affinity%20persistence,-Source%20address%20affinity)
+* [Fortinet](https://help.fortinet.com/fadc/4-8-0/olh/Content/FortiADC/handbook/slb_persistence.htm)
+* [Huwaei](https://info.support.huawei.com/hedex/api/pages/EDOC1100149308/AEJ0713J/18/resources/cli/session_persistence.html)
+* [NetScaler](https://docs.netscaler.com/en-us/citrix-adc/current-release/load-balancing/load-balancing-persistence/no-rule-persistence#:~:text=For%20IP%2Dbased%20persistence%2C%20you%20can%20also%20set%20the%20persistMask%20parameter)
+* [AVI](https://techdocs.broadcom.com/us/en/vmware-security-load-balancing/avi-load-balancer/avi-load-balancer/30-2/load-balancing-overview/persistence/client-ip-persistence.html)
diff --git a/geps/gep-3798/metadata.yaml b/geps/gep-3798/metadata.yaml
new file mode 100644
index 00000000..e7d33a7c
--- /dev/null
+++ b/geps/gep-3798/metadata.yaml
@@ -0,0 +1,37 @@
+apiVersion: internal.gateway.networking.k8s.io/v1alpha1
+kind: GEPDetails
+number: 3798
+name: Client IP-Based Session Persistence
+status: Provisional
+# Any authors who contribute to the GEP in any way should be listed here using
+# their GitHub handle.
+authors:
+  - arihantg
+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:
+    - number: 1619
+      name: Session Persistence
+      description: Session Persistence via BackendLBPolicy
+  
+# 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-696/index.md b/geps/gep-696/index.md
index bedcc6e6..4a4a97dd 100644
--- a/geps/gep-696/index.md
+++ b/geps/gep-696/index.md
@@ -47,6 +47,8 @@ Every feature should:
 3. Not exceed 128 characters.
 4. Contain only letters and numbers
 
+GEPs cannot move to Experimental without a Feature Name.
+
 ### Conformance tests 
 
 Conformance tests file names should try to follow the `pascal-case-name.go` format.
diff --git a/geps/gep-91/index.md b/geps/gep-91/index.md
index 6fddddb5..5d28c9a1 100644
--- a/geps/gep-91/index.md
+++ b/geps/gep-91/index.md
@@ -1,4 +1,4 @@
-# GEP-91: Client Certificate Validation for TLS terminating at the Gateway Listener
+# GEP-91: Client Certificate Validation for TLS terminating at the Gateway
 
 * Issue: [#91](https://github.com/kubernetes-sigs/gateway-api/issues/91)
 * Status: Implementable
@@ -8,31 +8,18 @@
 ## TLDR
 
 This GEP proposes a way to validate the TLS certificate presented by the frontend client to the server
-(Gateway Listener in this case) during a [TLS Handshake Protocol][].
+(Gateway in this case) during a [TLS Handshake Protocol][].
 
 ## Goals
 
-* Define an API field to specify the CA Certificate within the Gateway Listener 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.
+* 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.
+* 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.
 
-## Existing support in Implementations
-
-This feature is widely supported in implementations that support Gateway API.
-This table highlights the support. Please feel free to add any missing implementations not mentioned below.
-
-| Implementation | Support       |
-|----------------|------------|
-| Apache APISIX  | [ApisixTls.Client.CASecret](https://apisix.apache.org/docs/ingress-controller/tutorials/mtls/#mutual-authentication)      |
-| Contour        | [HTTPProxy.Spec.VirtualHost.Tls.ClientValidation.CASecret](https://projectcontour.io/docs/v1.17.1/config/tls-termination/)      |
-| Emissary Ingress| [TlSContext.Spec.Secret](https://www.getambassador.io/docs/emissary/latest/topics/running/tls/mtls)     |
-| Gloo Edge      | [VirtualService.Spec.SSLConfig.SecretRef](https://docs.solo.io/gloo-edge/latest/guides/security/tls/server_tls/#configuring-downstream-mtls-in-a-virtual-service)      |
-| Istio          | [Gateway.Spec.Servers.TLS.Mode](https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/#configure-a-mutual-tls-ingress-gateway)      |
-| Kong           | [mTLS Plugin](https://docs.konghq.com/hub/kong-inc/mtls-auth/)      |
-| Traefik        | [TLSOption.Spec.ClientAuth](https://doc.traefik.io/traefik/https/tls/#client-authentication-mtls)    |
-| NGINX Ingress Controller | [ingressMTLS](https://docs.nginx.com/nginx-ingress-controller/configuration/policy-resource/#ingressmtls)    |
-
 ### 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.
@@ -82,7 +69,7 @@ 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 
+    // 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"`
@@ -151,16 +138,56 @@ spec:
 This section highlights use cases that may be covered in a future iteration of this GEP
 
 * Using system CA certificates as the trust anchor to validate the certificates presented by the frontend client.
-* Supporting a mode where validating client certificates is optional, useful for debugging and migrating to strict TLS.
 * Supporting an optional `subjectAltNames` field within `FrontendTLSValidation` that can be used to specify one or more alternate names to verify the subject identity in the certificate presented by the client. This field falls under Authorization, the initial focus here is on Client Authentication and will be revisited when Authorization is tackled as a whole in the project.
 * Specifying the verification depth in the client certificate chain. This is being deferred because the default verification depth differs across implementations.
 
+## Existing support in Implementations
+
+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.
+
+| Implementation                      | Support                                                                                                                                                     | Granularity                  | Inline vs Policy |
+|------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------|------------------|
+| Acnodal EPIC                       |                                                                                                                                                             |                              |                  |
+| Airlock Microgateway               | [SidecarGateway.spec.applications[].downstream.tls.clientCertificate](https://docs.airlock.com/microgateway/latest/index/api/crds/sidecar-gateway/v1alpha1/index.html#sidecargatewayspecapplicationsdownstreamtls) | Per Listener                 | Inline           |
+| Amazon Elastic Kubernetes Service  |                                                                                                                                                             |                              |                  |
+| Apache APISIX                      | [ApisixTls.Client.CASecret](https://apisix.apache.org/docs/ingress-controller/tutorials/mtls/#mutual-authentication)                                       | Per SNI                      |                  |
+| Avi Kubernetes Operator            |                                                                                                                                                             |                              |                  |
+| Azure Application Gateway for Containers | [FrontendTLSPolicy](https://learn.microsoft.com/en-us/azure/application-gateway/for-containers/api-specification-kubernetes#alb.networking.azure.io/v1.FrontendTLSPolicy) | Per Gateway & Per Listener  | Policy           |
+| Cilium                             |                                                                                                                                                             |                              |                  |
+| Contour                            | [HTTPProxy.Spec.VirtualHost.Tls.ClientValidation.CASecret](https://projectcontour.io/docs/v1.17.1/config/tls-termination/)                                 | Per SNI                      | Inline           |
+| Easegress                          |                                                                                                                                                             |                              |                  |
+| Emissary Ingress                   | [TlSContext.Spec.CASecret](https://www.getambassador.io/docs/emissary/latest/howtos/client-cert-validation)                                                | Per SNI                      | Policy           |
+| Envoy Gateway                      | [ClientTrafficPolicy.Spec.TLS.ClientValidation](https://gateway.envoyproxy.io/docs/api/extension_types/#clientvalidationcontext)                           | Per Gateway & Per Listener  | Policy           |
+| Flomesh Service Mesh               |                                                                                                                                                             |                              |                  |
+| Gloo Gateway                       | [VirtualService.Spec.SSLConfig.SecretRef](https://docs.solo.io/gloo-edge/latest/guides/security/tls/server_tls/#configuring-downstream-mtls-in-a-virtual-service) | Per SNI                      | Inline           |
+| Google Cloud Service Mesh          |                                                                                                                                                             |                              |                  |
+| Google Kubernetes Engine           |                                                                                                                                                             |                              |                  |
+| HAProxy Ingress                    |                                                                                                                                                             |                              |                  |
+| HAProxy Kubernetes Ingress Controller | [ca-file](https://www.haproxy.com/documentation/haproxy-configuration-tutorials/security/authentication/client-certificate-authentication/#sidebar)      | Per SNI                      | Inline           |
+| HashiCorp Consul                   | [file-system-certificate](https://developer.hashicorp.com/consul/docs/north-south/api-gateway/secure-traffic/encrypt)                                      | Per Listener                 | Policy           |
+| Istio                              | [Gateway.Spec.Servers.TLS.Mode](https://istio.io/latest/docs/tasks/traffic-management/ingress/secure-ingress/#configure-a-mutual-tls-ingress-gateway)      | Per Server                  | Inline           |
+| kgateway                           |                                                                                                                                                             |                              |                  |
+| Kong Kubernetes Ingress Controller | [mTLS Plugin](https://docs.konghq.com/hub/kong-inc/mtls-auth/)                                                                                              | Per HTTP Proxy (Host/Port)   | Policy           |
+| Kong Gateway Operator              | [mTLS Plugin](https://docs.konghq.com/hub/kong-inc/mtls-auth/)                                                                                              | Per HTTP Proxy (Host/Port)   | Policy           |
+| Kuma                               |                                                                                                                                                             |                              |                  |
+| Linkerd                            |                                                                                                                                                             |                              |                  |
+| LiteSpeed Ingress Controller       |                                                                                                                                                             |                              |                  |
+| LoxiLB                             |                                                                                                                                                             |                              |                  |
+| NGINX Gateway Fabric               | [ingressMTLS](https://docs.nginx.com/nginx-ingress-controller/configuration/policy-resource/#ingressmtls)                                                  | Per Listener                 | Policy           |
+| ngrok Kubernetes Operator          | [TrafficPolicy.Terminate-TLS.Config.MutualTLSCertificateAuthorities](https://ngrok.com/docs/traffic-policy/actions/terminate-tls/#configuration-reference) | Per Endpoint (Host:Port)     | Policy           |
+| STUNner                            |                                                                                                                                                             |                              |                  |
+| Traefik Proxy                      | [TLSOption.Spec.ClientAuth](https://doc.traefik.io/traefik/https/tls/#client-authentication-mtls)                                                          | Per EntryPoint               | Inline           |
+| Tyk                                | [Enable Client Certificate](https://tyk.io/docs/basic-config-and-security/security/mutual-tls/client-mtls/#why-use-mutual-tls)                             | Per Gateway                  | Policy           |
+| WSO2 APK                           | [Authentication.Spec.Default.AuthTypes.MTLS](https://apk.docs.wso2.com/en/latest/catalogs/crds/authentication_types/#dp.wso2.com/v1alpha2.MutualSSLConfig) | Per API                      | Policy           |
+| Ingress-NGINX                      | [nginx.ingress.kubernetes.io/auth-tls-verify-client](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#client-certificate-authentication) | Per Ingress                  | Inline           |
 
 ## References
 
 [TLS Handshake Protocol]: https://www.rfc-editor.org/rfc/rfc5246#section-7.4
 [Certificate Path Validation]: https://www.rfc-editor.org/rfc/rfc5280#section-6
-[GatewayTLSConfig]: /references/spec/#gateway.networking.k8s.io/v1.GatewayTLSConfig
+[GatewayTLSConfig]: ../../reference/spec.md#gateway.networking.k8s.io/v1.GatewayTLSConfig
 [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
diff --git a/geps/gep-995/index.md b/geps/gep-995/index.md
index 6236d1a2..972fde10 100644
--- a/geps/gep-995/index.md
+++ b/geps/gep-995/index.md
@@ -9,7 +9,7 @@ Add a new optional `name` field to the route rule types ([GRPCRouteRule](../../r
 
 ## Goals
 
-* Support referencing individual route rules by name from other resources, such as from metaresources ([GEP-2648](../gep-2648/index.md#apply-policies-to-sections-of-a-resource).)
+* Support referencing individual route rules by name from other resources, such as from metaresources ([GEP-2648](../gep-2648/index.md#section-names).)
 * Support referencing individual route rules by name from condition messages propagated in the status stanza of route resources as suggested in https://github.com/kubernetes-sigs/gateway-api/issues/1696#issuecomment-1666258188.
 * Support referencing individual route rules by name at other observability and networking tools that are part of the ecosystem based on Gateway API.
 * Provide a rather intuitive API for users of Kubernetes who are familiar with the same pattern employed already by other kinds of resources where lists of complex elements can be declared – e.g. service [ports](https://kubernetes.io/docs/reference/kubernetes-api/service-resources/service-v1/#ServiceSpec), pod [containers](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#containers) and pod [volumes](https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#volumes).
diff --git a/geps/overview.md b/geps/overview.md
index 808cdb0a..d270e820 100644
--- a/geps/overview.md
+++ b/geps/overview.md
@@ -151,6 +151,8 @@ use the `experimental` Golang build tag to denote experimental functionality.
 Some other requirements must be met before marking a GEP `Experimental`:
 
 - the graduation criteria to reach `Standard` MUST be filled out
+- the GEP must have at least one Feature Name for features described inside that
+  will need to be tested by conformance tests.
 - a proposed probationary period (see next section) must be included in the GEP
   and approved by maintainers.
 
diff --git a/mkdocs.yml b/mkdocs.yml
index 4a4a7de3..4688e7f5 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -130,6 +130,9 @@ nav:
       - geps/gep-1494/index.md
       - geps/gep-1651/index.md
       - geps/gep-2648/index.md
+      - geps/gep-3379/index.md
+      - geps/gep-3792/index.md
+      - geps/gep-3793/index.md
     - Implementable:
       - geps/gep-91/index.md
       - geps/gep-3567/index.md
diff --git a/site-src/api-types/backendtlspolicy.md b/site-src/api-types/backendtlspolicy.md
index c0645d44..ac57bd04 100644
--- a/site-src/api-types/backendtlspolicy.md
+++ b/site-src/api-types/backendtlspolicy.md
@@ -139,10 +139,10 @@ Status defines the observed state of the BackendTLSPolicy and is not user-config
 way you do for other Gateway API objects to verify correct operation.  Note that the status in BackendTLSPolicy
 uses `PolicyAncestorStatus` to allow you to know which parentReference set that particular status.
 
-[backendtlspolicy]: /references/spec/#gateway.networking.k8s.io/v1alpha3.BackendTLSPolicy
-[validation]: /references/spec/#gateway.networking.k8s.io/v1alpha3.BackendTLSPolicy.Validation
-[caCertificateRefs]: /references/spec/#gateway.networking.k8s.io/v1alpha3.BackendTLSPolicyValidation.CACertificateRefs
-[wellKnownCACertificates]: /references/spec/#gateway.networking.k8s.io/v1alpha3.BackendTLSPolicyValidation.WellKnownCACertificates
-[hostname]: /references/spec/#gateway.networking.k8s.io/v1.PreciseHostname
+[backendtlspolicy]: ../reference/spec.md#gateway.networking.k8s.io/v1alpha3.BackendTLSPolicy
+[validation]: ../reference/spec.md#gateway.networking.k8s.io/v1alpha3.BackendTLSPolicy.Validation
+[caCertificateRefs]: ../reference/spec.md#gateway.networking.k8s.io/v1alpha3.BackendTLSPolicyValidation.CACertificateRefs
+[wellKnownCACertificates]: ../reference/spec.md#gateway.networking.k8s.io/v1alpha3.BackendTLSPolicyValidation.WellKnownCACertificates
+[hostname]: ../reference/spec.md#gateway.networking.k8s.io/v1.PreciseHostname
 [rfc-3986]: https://tools.ietf.org/html/rfc3986
-[targetRefs]: /references/spec/#gateway.networking.k8s.io/v1alpha2.PolicyTargetReference
+[targetRefs]: ../reference/spec.md#gateway.networking.k8s.io/v1alpha2.PolicyTargetReference
diff --git a/site-src/api-types/backendtrafficpolicy.md b/site-src/api-types/backendtrafficpolicy.md
index b64bc110..61dd6452 100644
--- a/site-src/api-types/backendtrafficpolicy.md
+++ b/site-src/api-types/backendtrafficpolicy.md
@@ -86,8 +86,8 @@ backendRef. TargetRefs is a required object reference, specifying a Backend via
 its Name, Kind, and Group. Currently, TargetRefs can not be scoped to
 specific ports on a service. 
 
-[backendtrafficpolicy]: /references/specx/#xbackendtrafficpolicy
+[backendtrafficpolicy]: /references/specx.md#xbackendtrafficpolicy
 [localpolicytargetreference]: /references/spec/#gateway.networking.k8s.io/v1alpha2.LocalPolicyTargetReference
-[retryConstraint]: /references/specx/#retryconstraint
+[retryConstraint]: /references/specx.md#retryconstraint
 [sessionPersistence]: /references/spec/#gateway.networking.k8s.io/v1.SessionPersistence
 [httproute]: /references/spec/#https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1beta1.HTTPRoute
diff --git a/site-src/api-types/grpcroute.md b/site-src/api-types/grpcroute.md
index 69dcfb40..2b6188ad 100644
--- a/site-src/api-types/grpcroute.md
+++ b/site-src/api-types/grpcroute.md
@@ -225,7 +225,7 @@ on `weight` and other fields.
     For more information on release channels, refer to our
     [versioning guide](../concepts/versioning.md).
 
-GRPCRoute Rules include an optional `name` field. The applications for the name of a route rule are implementation-specific. It can be used to reference individual route rules by name from other resources, such as in the `sectionName` field of metaresources ([GEP-2648](../geps/gep-2648/index.md#apply-policies-to-sections-of-a-resource)), in the status stanzas of resources related to the route object, to identify internal configuration objects generated by the implementation from GRPCRoute Rule, etc.
+GRPCRoute Rules include an optional `name` field. The applications for the name of a route rule are implementation-specific. It can be used to reference individual route rules by name from other resources, such as in the `sectionName` field of metaresources ([GEP-2648](../geps/gep-2648/index.md#section-names)), in the status stanzas of resources related to the route object, to identify internal configuration objects generated by the implementation from GRPCRoute Rule, etc.
 
 If specified, the value of the name field must comply with the [`SectionName`](https://github.com/kubernetes-sigs/gateway-api/blob/v1.0.0/apis/v1/shared_types.go#L607-L624) type.
 
diff --git a/site-src/api-types/httproute.md b/site-src/api-types/httproute.md
index c9d96dee..0551a37c 100644
--- a/site-src/api-types/httproute.md
+++ b/site-src/api-types/httproute.md
@@ -271,7 +271,7 @@ Reference the [timeouts][timeouts] API documentation for additional details.
     For more information on release channels, refer to our
     [versioning guide](../concepts/versioning.md).
 
-HTTPRoute Rules include an optional `name` field. The applications for the name of a route rule are implementation-specific. It can be used to reference individual route rules by name from other resources, such as in the `sectionName` field of metaresources ([GEP-2648](../geps/gep-2648/index.md#apply-policies-to-sections-of-a-resource)), in the status stanzas of resources related to the route object, to identify internal configuration objects generated by the implementation from HTTPRoute Rule, etc.
+HTTPRoute Rules include an optional `name` field. The applications for the name of a route rule are implementation-specific. It can be used to reference individual route rules by name from other resources, such as in the `sectionName` field of metaresources ([GEP-2648](../geps/gep-2648/index.md#section-names)), in the status stanzas of resources related to the route object, to identify internal configuration objects generated by the implementation from HTTPRoute Rule, etc.
 
 If specified, the value of the name field must comply with the [`SectionName`](https://github.com/kubernetes-sigs/gateway-api/blob/v1.0.0/apis/v1/shared_types.go#L607-L624) type.
 
diff --git a/site-src/blog/2021/introducing-v1alpha2.md b/site-src/blog/2021/introducing-v1alpha2.md
index fe231f9f..55f5231e 100644
--- a/site-src/blog/2021/introducing-v1alpha2.md
+++ b/site-src/blog/2021/introducing-v1alpha2.md
@@ -146,4 +146,4 @@ We still have lots more to work on. Some of our next items to discuss include:
 * L4 Route matching
 
 If these kinds of topics interest you, we'd love to have your input. Refer to
-our [community page](/contributing/community) to see how you can get involved.
+our [community page](../../contributing/index.md) to see how you can get involved.
diff --git a/site-src/blog/2022/graduating-to-beta.md b/site-src/blog/2022/graduating-to-beta.md
index 70064b7f..7b0e0115 100644
--- a/site-src/blog/2022/graduating-to-beta.md
+++ b/site-src/blog/2022/graduating-to-beta.md
@@ -70,12 +70,12 @@ page][community] which includes links to the Slack channel and community meeting
 
 [crd]:https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/
 [concepts]:../../concepts/api-overview.md
-[guides]:/guides/getting-started/
+[guides]:../../guides/index.md
 [impl]:../../implementations.md
-[install-crds]:/guides/getting-started/#install-the-crds
+[install-crds]:../../guides/index.md#installing-gateway-api
 [issue]:https://github.com/kubernetes-sigs/gateway-api/issues/new/choose
 [disc]:https://github.com/kubernetes-sigs/gateway-api/discussions
-[community]:/contributing/community/
+[community]:../../contributing/index.md
 
 ## Release highlights
 
@@ -128,7 +128,7 @@ For this release we've added the following experimental features:
 - [Routes can attach to Gateways by specifying port numbers](../../geps/gep-957/index.md)
 - [URL rewrites and path redirects](../../geps/gep-726/index.md)
 
-[ch]:../../concepts/versioning.md#release-channels-eg-experimental-standard
+[ch]:../../concepts/versioning.md#release-channels
 
 ### Other improvements
 
@@ -146,12 +146,12 @@ possible integration.
 We are pleased to announce that the service mesh community, including
 representatives from Cilium Service Mesh, Consul, Istio, Kuma, Linkerd, NGINX
 Service Mesh and Open Service Mesh, is coming together to form the [GAMMA
-Initiative](/concepts/gamma/), a dedicated
+Initiative](../../mesh/index.md), a dedicated
 workstream within the Gateway API subproject focused on Gateway API for Mesh
 Management and Administration.
 
 This group will deliver [enhancement
-proposals](/v1beta1/contributing/gep/) consisting
+proposals](../../contributing/enhancement-requests.md) consisting
 of resources, additions, and modifications to the Gateway API specification for
 mesh and mesh-adjacent use-cases.
 
@@ -169,11 +169,11 @@ As we continue to mature the API for production use cases, here are some of the
 - [Route delegation][pr1085]
 - Layer 4 API maturity: Graduating [TCPRoute][tcpr], [UDPRoute][udpr] and
   [TLSRoute][tlsr] to beta
-- [GAMMA Initiative](/concepts/gamma/) - Gateway API for Service Mesh
+- [GAMMA Initiative](../../mesh/index.md) - Gateway API for Service Mesh
 
 If there's something on this list you want to get involved in, or there's
 something not on this list that you want to advocate for to get on the roadmap
-please join us in the #sig-network-gateway-api channel on Kubernetes Slack or our weekly [community calls](/contributing/community/#meetings).
+please join us in the #sig-network-gateway-api channel on Kubernetes Slack or our weekly [community calls](../../contributing/index.md#meetings).
 
 [gep1016]:https://github.com/kubernetes-sigs/gateway-api/blob/master/geps/gep-1016.md
 [grpc]:https://grpc.io/
@@ -181,4 +181,4 @@ please join us in the #sig-network-gateway-api channel on Kubernetes Slack or ou
 [tcpr]:https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/tcproute_types.go
 [udpr]:https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/udproute_types.go
 [tlsr]:https://github.com/kubernetes-sigs/gateway-api/blob/main/apis/v1alpha2/tlsroute_types.go
-[community]:/contributing/community/
+[community]:../../contributing/index.md
diff --git a/site-src/blog/2023/0829-mesh-support.md b/site-src/blog/2023/0829-mesh-support.md
index 6b79dc63..7bc15c44 100644
--- a/site-src/blog/2023/0829-mesh-support.md
+++ b/site-src/blog/2023/0829-mesh-support.md
@@ -185,21 +185,21 @@ Although these are [Experimental][status] patterns, note that they are
 available in the [`standard` release channel][ch], since the GAMMA initiative
 has not needed to introduce new resources or fields to date.
 
-[gamma]:/concepts/gamma/
-[status]:../../geps/overview.md#status
-[ch]:../../concepts/versioning.md#release-channels-eg-experimental-standard
+[gamma]:../../mesh/index.md
+[status]:../../geps/overview.md#gep-states
+[ch]:../../concepts/versioning.md#release-channels
 [cel]:https://kubernetes.io/docs/reference/using-api/cel/
 [crd]:https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/
 [concepts]:../../concepts/api-overview.md
 [geps]:../../contributing/enhancement-requests.md
-[guides]:/guides/getting-started/
+[guides]:../../guides/index.md
 [impl]:../../implementations.md
-[install-crds]:/guides/getting-started/#install-the-crds
+[install-crds]:../../guides/index.md#installing-gateway-api
 [issue]:https://github.com/kubernetes-sigs/gateway-api/issues/new/choose
 [disc]:https://github.com/kubernetes-sigs/gateway-api/discussions
-[community]:/contributing/community/
-[mesh-routing]:/concepts/gamma/#how-the-gateway-api-works-for-service-mesh
-[GEP-1426]:/geps/gep-1426/
+[community]:../../contributing/index.md
+[mesh-routing]:../../mesh/index.md
+[GEP-1426]:../../geps/gep-1294/index.md
 [GEP-1324]:../../geps/gep-1324/index.md
 [GEP-1686]:../../geps/gep-1686/index.md
 [GEP-1709]:../../geps/gep-1709/index.md
diff --git a/site-src/blog/index.md b/site-src/blog/index.md
index 98f4bcb1..85027e3d 100644
--- a/site-src/blog/index.md
+++ b/site-src/blog/index.md
@@ -17,7 +17,7 @@ your feedback!
 
 [:octicons-arrow-right-24: Continue reading][Gateway API: Introducing Service Mesh Support!]
 
-[status]:../geps/overview.md#status
+[status]:../geps/overview.md#gep-states
 [Gateway API: Introducing Service Mesh Support!]:2023/0829-mesh-support.md
 
 ## [Gateway API Graduates to Beta]
diff --git a/site-src/concepts/api-overview.md b/site-src/concepts/api-overview.md
index d04f893b..20db51b0 100644
--- a/site-src/concepts/api-overview.md
+++ b/site-src/concepts/api-overview.md
@@ -219,7 +219,7 @@ The following is required for a Route to be attached to a Gateway:
 
     The `Port` field described below is currently only included in the
     "Experimental" channel of Gateway API. For more information on release
-    channels, refer to the [related documentation](versioning.md#adding-experimental-fields).
+    channels, refer to the [related documentation](versioning.md#release-channels).
 
 A Route can reference a Gateway by specifying the namespace (optional if the
 Route and the Gateway are in the same namespace) and name of the Gateway in
@@ -326,8 +326,8 @@ to any traffic directed to the Service. How and which Routes attach to a given
 Service is controlled by the Routes themselves (working with Kubernetes RBAC),
 as covered in the [GAMMA routing documentation].
 
-[GAMMA]:/concepts/gamma
-[GAMMA routing documentation]:/concepts/gamma#gateway-api-for-mesh
+[GAMMA]:../mesh/index.md
+[GAMMA routing documentation]:../mesh/index.md#connecting-routes-and-services
 [service mesh]:glossary.md#service-mesh
 
 ## Extension points
diff --git a/site-src/concepts/use-cases.md b/site-src/concepts/use-cases.md
index dfe68d2a..3199e0a6 100644
--- a/site-src/concepts/use-cases.md
+++ b/site-src/concepts/use-cases.md
@@ -14,9 +14,9 @@ organizations, they all have distinct concerns that we need to consider
 separately.)
 
 [roles and personas]:roles-and-personas.md
-[Ana]:roles-and-personas.md#ana
-[Chihiro]:roles-and-personas.md#chihiro
-[Ian]:roles-and-personas.md#ian
+[Ana]:roles-and-personas.md#key-roles-and-personas
+[Chihiro]:roles-and-personas.md#key-roles-and-personas
+[Ian]:roles-and-personas.md#key-roles-and-personas
 
 ## The Use Cases
 
@@ -148,7 +148,7 @@ advantage of the service mesh, with custom routing logic, without any
 bottlenecks in requests to Chihiro or Ian.
 
 [east/west]:glossary.md#eastwest-traffic
-[GAMMA]:/concepts/gamma/
+[GAMMA]:../mesh/index.md
 [service mesh]:glossary.md#service-mesh
 
 ## Gateway and mesh use case
diff --git a/site-src/contributing/release-cycle.md b/site-src/contributing/release-cycle.md
index 43a811df..f25686d1 100644
--- a/site-src/contributing/release-cycle.md
+++ b/site-src/contributing/release-cycle.md
@@ -79,6 +79,21 @@ candidates. These release candidates will enable implementations to test against
 our release, work out any bugs, and gather early feedback on the viability of
 the release.
 
+## What happens when GEPs are unable to meet a timeline?
+
+There will be situations where the above phases and timelines can't be met by
+a GEP for one reason or another. In special circumstances (particularly, when it
+is is anticipated that only a little bit more time is needed to meet the goal) a
+time extension _might_ be granted if requested by the GEP authors, at the
+discretion of the maintainers.
+
+In the normal case however, when a GEP misses the timeline for a phase it will
+be pulled out of the release to maximize bandwidth and reduce disruptions to the
+overall release timeline. In such a case the Gateway API maintainers will stop
+progression and set the status of the GEP to a halted status (such as `Deferred`
+or `Declined`) with a note on the GEP explaining why it reached this status and
+what it would take to get it re-approved for work in a later iteration.
+
 ## Contributions Welcome in Each Phase
 
 The following table illustrates when different kinds of contributions will be
diff --git a/site-src/faq.md b/site-src/faq.md
index 0e580689..e02f9032 100644
--- a/site-src/faq.md
+++ b/site-src/faq.md
@@ -1,7 +1,8 @@
 # Frequently Asked Questions (FAQ)
 
 #### How can I get involved with Gateway API?
-The [community](/contributing/community) page keeps track of how to get involved
+
+The [community](contributing/index.md) page keeps track of how to get involved
 with the project.
 
 #### Will Gateway API replace the Ingress API?
diff --git a/site-src/guides/crd-management.md b/site-src/guides/crd-management.md
index d2cfd588..7a9c05cc 100644
--- a/site-src/guides/crd-management.md
+++ b/site-src/guides/crd-management.md
@@ -33,7 +33,7 @@ explores one possible approach implementations could use to accomplish this.
 ## Upgrading to a new version
 
 Gateway API releases CRDs in two [release
-channels](../concepts/versioning.md#release-channels-eg-experimental-standard).
+channels](../concepts/versioning.md#release-channels).
 Sticking with standard channel CRDs will ensure CRD upgrades are both simpler
 and safer.
 
diff --git a/site-src/guides/migrating-from-ingress.md b/site-src/guides/migrating-from-ingress.md
index bef5a6c4..77fef68d 100644
--- a/site-src/guides/migrating-from-ingress.md
+++ b/site-src/guides/migrating-from-ingress.md
@@ -251,7 +251,7 @@ In contrast, Gateway API specifies how to merge rules and resolve conflicts:
 * A Gateway implementation must merge the routing rules from all HTTPRoutes
   attached to a listener.
 * Conflicts must be handled as
-  prescribed in [API Design Guide: Conflicts](/guides/api-design/#conflicts). For example, more specific
+  prescribed in [API Design Guide: Conflicts](../guides/api-design.md#conflicts). For example, more specific
   matches in a routing rule win over the less specific ones.
 
 #### Default Backend
diff --git a/site-src/guides/multiple-ns.md b/site-src/guides/multiple-ns.md
index dce09dc6..6805f2c5 100644
--- a/site-src/guides/multiple-ns.md
+++ b/site-src/guides/multiple-ns.md
@@ -158,7 +158,7 @@ After these three Routes are deployed, they will all be attached to the
 list of routing rules. [Routing precedence](../reference/spec.md#gateway.networking.k8s.io/v1.HTTPRouteRule)
 between these routing rules is determined by most specific match and
 conflicts are handled according to [conflict
-resolution](/concepts/guidelines#conflicts). This provides predictable and
+resolution](api-design.md#conflicts). This provides predictable and
 deterministic merging of routing rules between independent users.
 
 Thanks to cross-Namespace routing, the Foobar Corporation can distribute
diff --git a/site-src/implementations.md b/site-src/implementations.md
index 06b0e792..7460c920 100644
--- a/site-src/implementations.md
+++ b/site-src/implementations.md
@@ -101,7 +101,7 @@ cover, and documentation to help users get started.
 [39]:#kubvernor
 
 
-[gamma]:/concepts/gamma/
+[gamma]:mesh/index.md
 
 
 
@@ -222,7 +222,7 @@ For help and support with Contour's implementation, [create an issue][contour-is
 
 [contour]:https://projectcontour.io
 [contour-release]:https://github.com/projectcontour/contour/releases/tag/v1.30.0
-[contour-standard]:concepts/versioning.md#release-channels-eg-experimental-standard
+[contour-standard]:concepts/versioning.md#release-channels
 [contour-guide]:https://projectcontour.io/docs/1.30/guides/gateway-api/
 [contour-issue-new]:https://github.com/projectcontour/contour/issues/new/choose
 [contour-slack]:https://kubernetes.slack.com/archives/C8XRH2R4J
@@ -496,11 +496,12 @@ If you have any suggestions or experience issues with NGINX Gateway Fabric, plea
 ### ngrok Kubernetes Operator
 
 [ngrok Kubernetes Operator][ngrok-k8s-operator] After adding preliminary support last year, the [ngrok Kubernetes Operator][ngrok-k8s-operator] supports the entire core Gateway API. This includes:
--Routes (HTTPRoute, TCPRoute, TLSRoute) + RouteMatches (Header, Path, +more)
--Filters: Header, Redirect, Rewrite + more
--Backends: Backend Filters + Weighted balancing
--ReferenceGrant: RBAC for multi-tenant clusters handling
--Traffic Policy as an extensionRef or annotation when the Gateway API isn’t flexible enough
+
+- Routes (HTTPRoute, TCPRoute, TLSRoute) + RouteMatches (Header, Path, +more)
+- Filters: Header, Redirect, Rewrite + more
+- Backends: Backend Filters + Weighted balancing
+- ReferenceGrant: RBAC for multi-tenant clusters handling
+- Traffic Policy as an extensionRef or annotation when the Gateway API isn’t flexible enough
 
 You can read our [docs][ngrok-k8s-gwapi-docs] for more information. If you have any feature requests or bug reports, please [create an issue][ngrok-issue-new]. You can also reach out for help on [Slack][ngrok-slack]
 
@@ -508,7 +509,7 @@ You can read our [docs][ngrok-k8s-gwapi-docs] for more information. If you have
 [ngrok]:https://ngrok.com
 [ngrok-k8s-gwapi-docs]:https://ngrok.com/docs/k8s/
 [ngrok-issue-new]: https://github.com/ngrok/ngrok-operator/issues/new/choose
-
+[ngrok-slack]:https://ngrokcommunity.slack.com/channels/general
 
 ### STUNner
 
diff --git a/site-src/index.md b/site-src/index.md
index 417c3f23..088315b2 100644
--- a/site-src/index.md
+++ b/site-src/index.md
@@ -69,15 +69,15 @@ individual route resources (such as [HTTPRoute](api-types/httproute.md)) are
 mesh to manage traffic from any traffic directed to that Service while
 preserving the role-oriented nature of Gateway API.
 
-To date, [GAMMA](mesh/gamma.md) has been able to support mesh functionality with
+To date, [GAMMA](mesh/index.md) has been able to support mesh functionality with
 fairly minimal changes to Gateway API. One particular area that has
 rapidly become critical for GAMMA, though, is the definition of the different
 [facets of the Service resource][service-facets].
 
-[gamma]:/concepts/gamma/
+[gamma]:mesh/index.md
 [service-mesh]:concepts/glossary.md#service-mesh
-[service-facets]:/concepts/service-facets
-[mesh-attachment]:/concepts/gamma#gateway-api-for-mesh
+[service-facets]:mesh/service-facets.md
+[mesh-attachment]:mesh/index.md
 
 ## Getting started
 
@@ -89,7 +89,7 @@ you the necessary background:
 - [User guides](guides/index.md)
 - [Implementations](implementations.md)
 - [API reference spec](reference/spec.md)
-- [Community links](/contributing/community) and [developer guide](contributing/devguide.md)
+- [Community links](contributing/index.md) and [developer guide](contributing/devguide.md)
 
 ## Gateway API concepts
 The following design goals drive the concepts of Gateway API. These
@@ -189,7 +189,7 @@ It allows organizations to move key functions, such as authentication and
 authorization or limiting the number of requests between applications, to a
 centrally managed location. An API gateway functions as a common interface to (often external) API consumers.
 
-Gateway API is an interface, defined as a set of Kubernetes resources, that 
+Gateway API is an interface, defined as a set of Kubernetes resources, that
 models service networking in Kubernetes. One of the main resources is a `Gateway`,
 which declares the Gateway type (or class) to instantiate and its configuration.
 As a Gateway provider, you can implement Gateway API to model Kubernetes service
@@ -205,7 +205,7 @@ project being built to improve and standardize service networking in Kubernetes.
 Check out the [implementations reference](implementations.md) to see the latest
 projects & products that support Gateway. If you are interested in contributing
 to or building an implementation using Gateway API then don’t hesitate to [get
-involved!](/contributing/community)
+involved!](contributing/index.md)
 
 [sig-network]: https://github.com/kubernetes/community/tree/master/sig-network
 
diff --git a/site-src/mesh/gamma.md b/site-src/mesh/gamma.md
index 6071711c..fd4b62a8 100644
--- a/site-src/mesh/gamma.md
+++ b/site-src/mesh/gamma.md
@@ -44,5 +44,5 @@ The simplest way to get started is to attend one of the regular Gateway API
 [role-oriented]:../concepts/roles-and-personas.md
 [geps]:../geps/overview.md
 [contributor-ladder]:../contributing/contributor-ladder.md
-[meetings]:/contributing/community/#meetings
+[meetings]:../contributing/index.md/#meetings
 [GAMMA leads]:https://github.com/kubernetes-sigs/gateway-api/blob/main/OWNERS_ALIASES#L23
diff --git a/site-src/mesh/index.md b/site-src/mesh/index.md
index 98891909..0d56793f 100644
--- a/site-src/mesh/index.md
+++ b/site-src/mesh/index.md
@@ -36,7 +36,7 @@ Service.
 [TCPRoute]: ../concepts/api-overview.md#tcproute-and-udproute
 [Service]: https://kubernetes.io/docs/concepts/services-networking/service/
 [service-mesh]:../concepts/glossary.md#service-mesh
-[service-facets]:/concepts/service-facets
+[service-facets]:service-facets.md
 
 ## Connecting routes and services <a name="gateway-api-for-mesh">
 
diff --git a/site-src/mesh/service-facets.md b/site-src/mesh/service-facets.md
index 9b5f880b..96633fca 100644
--- a/site-src/mesh/service-facets.md
+++ b/site-src/mesh/service-facets.md
@@ -46,5 +46,5 @@ formalize guidance for this use case.
 [Service]: https://kubernetes.io/docs/concepts/services-networking/service/
 [north/south]:../concepts/glossary.md#northsouth-traffic
 [east/west traffic]:../concepts/glossary.md#eastwest-traffic
-[gamma]:/concepts/gamma/
+[gamma]:gamma.md
 [Ana]:../concepts/roles-and-personas.md#ana



Test patch:
diff --git a/conformance/tests/mesh/httproute-weight.go b/conformance/tests/mesh/httproute-weight.go
index 09ef3465..cc296d92 100644
--- a/conformance/tests/mesh/httproute-weight.go
+++ b/conformance/tests/mesh/httproute-weight.go
@@ -18,13 +18,16 @@ package meshtests
 
 import (
 	"cmp"
+	"crypto/rand"
 	"errors"
 	"fmt"
 	"math"
+	"math/big"
 	"slices"
 	"strings"
 	"sync"
 	"testing"
+	"time"
 
 	"golang.org/x/sync/errgroup"
 
@@ -89,7 +92,11 @@ func testDistribution(t *testing.T, client echo.MeshPod, expected http.ExpectedR
 	g.SetLimit(concurrentRequests)
 	for i := 0.0; i < totalRequests; i++ {
 		g.Go(func() error {
-			_, cRes, err := client.CaptureRequestResponseAndCompare(t, expected)
+			uniqueExpected := expected
+			if err := addEntropy(&uniqueExpected); err != nil {
+				return fmt.Errorf("error adding entropy: %w", err)
+			}
+			_, cRes, err := client.CaptureRequestResponseAndCompare(t, uniqueExpected)
 			if err != nil {
 				return fmt.Errorf("failed: %w", err)
 			}
@@ -141,3 +148,54 @@ 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 951571f7..ccb259ad 100644
--- a/conformance/utils/suite/suite_test.go
+++ b/conformance/utils/suite/suite_test.go
@@ -22,9 +22,13 @@ 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"
+	"sigs.k8s.io/controller-runtime/pkg/client/fake"
 
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
 	confv1 "sigs.k8s.io/gateway-api/conformance/apis/v1"
 	"sigs.k8s.io/gateway-api/pkg/consts"
 	"sigs.k8s.io/gateway-api/pkg/features"
@@ -217,7 +221,7 @@ var (
 func TestSuiteReport(t *testing.T) {
 	testCases := []struct {
 		name                      string
-		features                  sets.Set[features.FeatureName]
+		features                  FeaturesSet
 		extendedSupportedFeatures map[ConformanceProfileName]sets.Set[features.FeatureName]
 		profiles                  sets.Set[ConformanceProfileName]
 		skipProvisionalTests      bool
@@ -276,6 +280,7 @@ func TestSuiteReport(t *testing.T) {
 					coreProvisionalTest.ShortName,
 					extendedProvisionalTest.ShortName,
 				},
+				InferredSupportedFeatures: true,
 			},
 		},
 		{
@@ -385,6 +390,7 @@ func TestSuiteReport(t *testing.T) {
 						},
 					},
 				},
+				InferredSupportedFeatures: true,
 			},
 		},
 	}
@@ -407,3 +413,128 @@ func TestSuiteReport(t *testing.T) {
 		})
 	}
 }
+
+var statusFeatureNames = []string{
+	"Gateway",
+	"GatewayPort8080",
+	"HTTPRoute",
+	"HTTPRouteHostRewrite",
+	"HTTPRouteMethodMatching",
+	"HTTPRoutePathRewrite",
+	"TTPRouteQueryParamMatching",
+	"HTTPRouteResponseHeaderModification",
+	"ReferenceGrant",
+}
+
+func TestInferSupportedFeatures(t *testing.T) {
+	testCases := []struct {
+		name               string
+		allowAllFeatures   bool
+		supportedFeatures  FeaturesSet
+		exemptFeatures     FeaturesSet
+		ConformanceProfile sets.Set[ConformanceProfileName]
+		expectedFeatures   FeaturesSet
+		expectedIsInferred bool
+	}{
+		{
+			name:               "properly infer supported features",
+			expectedFeatures:   namesToFeatureSet(statusFeatureNames),
+			expectedIsInferred: true,
+		},
+		{
+			name:              "no features",
+			supportedFeatures: sets.New[features.FeatureName]("Gateway"),
+			expectedFeatures:  sets.New[features.FeatureName]("Gateway"),
+		},
+		{
+			name:              "remove exempt features",
+			supportedFeatures: sets.New[features.FeatureName]("Gateway", "HTTPRoute"),
+			exemptFeatures:    sets.New[features.FeatureName]("HTTPRoute"),
+			expectedFeatures:  sets.New[features.FeatureName]("Gateway"),
+		},
+		{
+			name:             "allow all features",
+			allowAllFeatures: true,
+			expectedFeatures: features.SetsToNamesSet(features.AllFeatures),
+		},
+		{
+			name:               "supports conformance profile - core",
+			ConformanceProfile: sets.New(GatewayHTTPConformanceProfileName),
+			expectedFeatures:   namesToFeatureSet([]string{"Gateway", "HTTPRoute", "ReferenceGrant"}),
+		},
+	}
+
+	gwcName := "ochopintre"
+	gwc := &gatewayv1.GatewayClass{
+		ObjectMeta: metav1.ObjectMeta{
+			Name: gwcName,
+		},
+		Spec: gatewayv1.GatewayClassSpec{
+			ControllerName: "example.com/gateway-controller",
+		},
+		Status: gatewayv1.GatewayClassStatus{
+			Conditions: []metav1.Condition{
+				{
+					Type:    string(gatewayv1.GatewayConditionAccepted),
+					Status:  metav1.ConditionTrue,
+					Reason:  "Accepted",
+					Message: "GatewayClass is accepted and ready for use",
+				},
+			},
+			SupportedFeatures: featureNamesToSet(statusFeatureNames),
+		},
+	}
+	scheme := runtime.NewScheme()
+	scheme.AddKnownTypes(gatewayv1.SchemeGroupVersion, &gatewayv1.GatewayClass{})
+	fakeClient := fake.NewClientBuilder().
+		WithScheme(scheme).
+		WithObjects(gwc).
+		WithLists(&apiextensionsv1.CustomResourceDefinitionList{}).
+		Build()
+
+	gatewayv1.Install(fakeClient.Scheme())
+	apiextensionsv1.AddToScheme(fakeClient.Scheme())
+
+	for _, tc := range testCases {
+		options := ConformanceOptions{
+			AllowCRDsMismatch:          true,
+			GatewayClassName:           gwcName,
+			EnableAllSupportedFeatures: tc.allowAllFeatures,
+			SupportedFeatures:          tc.supportedFeatures,
+			ExemptFeatures:             tc.exemptFeatures,
+			ConformanceProfiles:        tc.ConformanceProfile,
+			Client:                     fakeClient,
+		}
+
+		t.Run(tc.name, func(t *testing.T) {
+			cSuite, err := NewConformanceTestSuite(options)
+			if err != nil {
+				t.Fatalf("error initializing conformance suite: %v", err)
+			}
+
+			if cSuite.IsInferredSupportedFeatures() != tc.expectedIsInferred {
+				t.Errorf("InferredSupportedFeatures mismatch: got %v, want %v", cSuite.IsInferredSupportedFeatures(), tc.expectedIsInferred)
+			}
+
+			if equal := cSuite.SupportedFeatures.Equal(tc.expectedFeatures); !equal {
+				t.Errorf("SupportedFeatures mismatch: got %v, want %v", cSuite.SupportedFeatures.UnsortedList(), tc.expectedFeatures.UnsortedList())
+			}
+		})
+	}
+}
+
+func featureNamesToSet(set []string) []gatewayv1.SupportedFeature {
+	var features []gatewayv1.SupportedFeature
+	for _, feature := range set {
+		features = append(features, gatewayv1.SupportedFeature{Name: gatewayv1.FeatureName(feature)})
+	}
+	return features
+}
+
+func namesToFeatureSet(names []string) FeaturesSet {
+	featureSet := FeaturesSet{}
+	for _, name := range names {
+		featureSet.Insert(features.FeatureName(name))
+	}
+	return featureSet
+}