Repository: envoyproxy/gateway

Issue:
controller panic when reloading configuration
```console
panic: duplicate metrics collector registration attempted                                                                                                                                │
│                                                                                                                                                                                          │
│ goroutine 2913921 [running]:                                                                                                                                                             │
│ github.com/prometheus/client_golang/prometheus.(*Registry).MustRegister(0xb327120, {0xc00c21e710?, 0xc00452e540?, 0x5?})                                                                 │
│     /home/runner/go/pkg/mod/github.com/prometheus/client_golang@v1.22.0/prometheus/registry.go:406 +0x65                                                                                 │
│ github.com/envoyproxy/gateway/internal/metrics/restclient.RegisterClientMetricsWithoutRequestTotal({0x8b84270, 0xb327120})                                                               │
│     /home/runner/work/gateway/gateway/internal/metrics/restclient/metrics.go:73 +0x69                                                                                                    │
│ github.com/envoyproxy/gateway/internal/metrics.(*Runner).newOptions(0xc00cc16920)                                                                                                        │
│     /home/runner/work/gateway/gateway/internal/metrics/register.go:115 +0x7ab                                                                                                            │
│ github.com/envoyproxy/gateway/internal/metrics.(*Runner).Start(0xc00cc16920, {0xc00338b440?, 0xc00ae225a0?})                                                                             │
│     /home/runner/work/gateway/gateway/internal/metrics/register.go:49 +0x1c5                                                                                                             │
│ github.com/envoyproxy/gateway/internal/cmd.startRunner({0x8b99228, 0xc00ae225a0}, 0xc0005e19d0, {0x8b7e880, 0xc00cc16920})                                                               │
│     /home/runner/work/gateway/gateway/internal/cmd/server.go:282 +0x10b                                                                                                                  │
│ github.com/envoyproxy/gateway/internal/cmd.startRunners({0x8b99228, 0xc00ae225a0}, 0xc0005e19d0)                                                                                         │
│     /home/runner/work/gateway/gateway/internal/cmd/server.go:232 +0x7e5                                                                                                                  │
│ github.com/envoyproxy/gateway/internal/cmd.server.func1({0x8b99228, 0xc00ae225a0}, 0xc0005e19d0)                                                                                         │
│     /home/runner/work/gateway/gateway/internal/cmd/server.go:68 +0x70                                                                                                                    │
│ github.com/envoyproxy/gateway/internal/envoygateway/config/loader.(*Loader).runHook.func1({0x8b99228?, 0xc00ae225a0?})                                                                   │
│     /home/runner/work/gateway/gateway/internal/envoygateway/config/loader/configloader.go:110 +0x2e                                                                                      │
│ created by github.com/envoyproxy/gateway/internal/envoygateway/config/loader.(*Loader).runHook in goroutine 64                                                                           │
│     /home/runner/work/gateway/gateway/internal/envoygateway/config/loader/configloader.go:109 +0x125
```

Hints from issue comments:

Solution patch:
diff --git a/api/v1alpha1/envoygateway_types.go b/api/v1alpha1/envoygateway_types.go
index 86a6c1f4e..022877315 100644
--- a/api/v1alpha1/envoygateway_types.go
+++ b/api/v1alpha1/envoygateway_types.go
@@ -173,7 +173,7 @@ type EnvoyGatewayLogging struct {
 }
 
 // EnvoyGatewayLogComponent defines a component that supports a configured logging level.
-// +kubebuilder:validation:Enum=default;provider;gateway-api;xds-translator;xds-server;infrastructure;global-ratelimit
+// +kubebuilder:validation:Enum=default;provider;gateway-api;xds-translator;xds-server;xds;infrastructure;global-ratelimit
 type EnvoyGatewayLogComponent string
 
 const (
@@ -193,6 +193,9 @@ const (
 	// LogComponentXdsServerRunner defines the "xds-server" runner component.
 	LogComponentXdsServerRunner EnvoyGatewayLogComponent = "xds-server"
 
+	// LogComponentXdsRunner defines the "xds" runner component.
+	LogComponentXdsRunner EnvoyGatewayLogComponent = "xds"
+
 	// LogComponentInfrastructureRunner defines the "infrastructure" runner component.
 	LogComponentInfrastructureRunner EnvoyGatewayLogComponent = "infrastructure"
 
diff --git a/api/v1alpha1/validation/envoygateway_validate.go b/api/v1alpha1/validation/envoygateway_validate.go
index 3814b78fa..37d9b63b5 100644
--- a/api/v1alpha1/validation/envoygateway_validate.go
+++ b/api/v1alpha1/validation/envoygateway_validate.go
@@ -144,6 +144,7 @@ func validateEnvoyGatewayLogging(logging *egv1a1.EnvoyGatewayLogging) error {
 			egv1a1.LogComponentGatewayAPIRunner,
 			egv1a1.LogComponentXdsTranslatorRunner,
 			egv1a1.LogComponentXdsServerRunner,
+			egv1a1.LogComponentXdsRunner,
 			egv1a1.LogComponentInfrastructureRunner,
 			egv1a1.LogComponentGlobalRateLimitRunner:
 			switch logLevel {
@@ -152,7 +153,7 @@ func validateEnvoyGatewayLogging(logging *egv1a1.EnvoyGatewayLogging) error {
 				return fmt.Errorf("envoy gateway logging level invalid. valid options: info/debug/warn/error")
 			}
 		default:
-			return fmt.Errorf("envoy gateway logging components invalid. valid options: system/provider/gateway-api/xds-translator/xds-server/infrastructure")
+			return fmt.Errorf("envoy gateway logging components invalid. valid options: system/provider/gateway-api/xds-translator/xds-server/xds/infrastructure")
 		}
 	}
 	return nil
diff --git a/examples/extension-server/go.mod b/examples/extension-server/go.mod
index c86026e17..7a265fb79 100644
--- a/examples/extension-server/go.mod
+++ b/examples/extension-server/go.mod
@@ -45,8 +45,8 @@ require (
 	golang.org/x/text v0.27.0 // indirect
 	golang.org/x/tools v0.35.0 // indirect
 	golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/examples/extension-server/go.sum b/examples/extension-server/go.sum
index d17ae3907..7abb864d9 100644
--- a/examples/extension-server/go.sum
+++ b/examples/extension-server/go.sum
@@ -37,8 +37,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
 github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
 github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a h1://KbezygeMJZCSHH+HgUZiTeSoiuFspbMg1ge+eFj18=
-github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a/go.mod h1:5hDyRhoBCxViHszMt12TnOpEI4VVi+U8Gm9iphldiMA=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
+github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
 github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
 github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@@ -160,10 +160,10 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 h1:0UOBWO4dC+e51ui0NFKSPbkHHiQ4TmrEfEZMLDyRmY8=
+google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 h1:MAKi5q709QWfnkkpNQ0M12hYJ1+e8qYVDyowc4U1XZM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
 google.golang.org/grpc v1.74.2 h1:WoosgB65DlWVC9FqI82dGsZhWFNBSLjQ84bjROOpMu4=
 google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeBEXrM=
 google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
diff --git a/go.mod b/go.mod
index c23591331..b4b06e99e 100644
--- a/go.mod
+++ b/go.mod
@@ -34,16 +34,16 @@ require (
 	github.com/go-openapi/strfmt v0.23.0
 	github.com/go-openapi/validate v0.24.0
 	github.com/golang/protobuf v1.5.4
-	github.com/google/cel-go v0.25.0
+	github.com/google/cel-go v0.26.0
 	github.com/google/go-cmp v0.7.0
 	github.com/google/go-containerregistry v0.20.6
-	github.com/miekg/dns v1.1.67
+	github.com/miekg/dns v1.1.68
 	github.com/ohler55/ojg v1.26.8
 	github.com/pkg/errors v0.9.1
-	github.com/prometheus/client_golang v1.22.0
+	github.com/prometheus/client_golang v1.23.0
 	github.com/prometheus/client_model v0.6.2
 	github.com/prometheus/common v0.65.0
-	github.com/quic-go/quic-go v0.52.0
+	github.com/quic-go/quic-go v0.54.0
 	github.com/replicatedhq/troubleshoot v0.121.2
 	github.com/shopspring/decimal v1.4.0
 	github.com/spf13/cobra v1.9.1
@@ -61,12 +61,12 @@ require (
 	go.opentelemetry.io/otel/metric v1.37.0
 	go.opentelemetry.io/otel/sdk v1.37.0
 	go.opentelemetry.io/otel/sdk/metric v1.37.0
-	go.opentelemetry.io/proto/otlp v1.7.0
+	go.opentelemetry.io/proto/otlp v1.7.1
 	go.uber.org/zap v1.27.0
-	golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476
+	golang.org/x/exp v0.0.0-20250718183923-645b1fa84792
 	golang.org/x/net v0.42.0
 	gomodules.xyz/jsonpatch/v2 v2.5.0
-	google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822
+	google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0
 	google.golang.org/grpc v1.74.2
 	google.golang.org/grpc/security/advancedtls v1.0.0
 	google.golang.org/protobuf v1.36.6
@@ -93,15 +93,15 @@ require (
 	4d63.com/gocheckcompilerdirectives v1.3.0 // indirect
 	4d63.com/gochecknoglobals v0.2.2 // indirect
 	al.essio.dev/pkg/shellescape v1.5.1 // indirect
-	buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250121211742-6d880cc6cc8d.1 // indirect
-	buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250613105001-9f2d3c737feb.1 // indirect
-	buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250606164443-9d1800bf4ccc.1 // indirect
-	buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250606164443-9d1800bf4ccc.1 // indirect
+	buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250718181942-e35f9b667443.1 // indirect
+	buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1 // indirect
+	buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250721151928-2b7ae473b098.1 // indirect
+	buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250721151928-2b7ae473b098.1 // indirect
 	buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1 // indirect
 	buf.build/go/app v0.1.0 // indirect
 	buf.build/go/bufplugin v0.9.0 // indirect
 	buf.build/go/interrupt v1.1.0 // indirect
-	buf.build/go/protovalidate v0.13.1 // indirect
+	buf.build/go/protovalidate v0.14.0 // indirect
 	buf.build/go/protoyaml v0.6.0 // indirect
 	buf.build/go/spdx v0.2.0 // indirect
 	buf.build/go/standard v0.1.0 // indirect
@@ -160,7 +160,7 @@ require (
 	github.com/bombsimon/wsl/v5 v5.1.0 // indirect
 	github.com/breml/bidichk v0.3.3 // indirect
 	github.com/breml/errchkjson v0.4.1 // indirect
-	github.com/bufbuild/buf v1.55.1 // indirect
+	github.com/bufbuild/buf v1.56.0 // indirect
 	github.com/bufbuild/protocompile v0.14.1 // indirect
 	github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 // indirect
 	github.com/butuzov/ireturn v0.4.0 // indirect
@@ -185,7 +185,7 @@ require (
 	github.com/containerd/errdefs/pkg v0.3.0 // indirect
 	github.com/containerd/log v0.1.0 // indirect
 	github.com/containerd/platforms v0.2.1 // indirect
-	github.com/containerd/stargz-snapshotter/estargz v0.16.3 // indirect
+	github.com/containerd/stargz-snapshotter/estargz v0.17.0 // indirect
 	github.com/containerd/typeurl/v2 v2.2.3 // indirect
 	github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect
 	github.com/containers/ocicrypt v1.2.1 // indirect
@@ -234,7 +234,6 @@ require (
 	github.com/go-openapi/swag v0.23.1 // indirect
 	github.com/go-redis/redis/v7 v7.4.1 // indirect
 	github.com/go-sql-driver/mysql v1.9.3 // indirect
-	github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
 	github.com/go-toolsmith/astcast v1.1.0 // indirect
 	github.com/go-toolsmith/astcopy v1.1.0 // indirect
 	github.com/go-toolsmith/astequal v1.2.0 // indirect
@@ -268,7 +267,6 @@ require (
 	github.com/google/go-intervals v0.0.2 // indirect
 	github.com/google/go-jsonnet v0.20.0 // indirect
 	github.com/google/gofuzz v1.2.0 // indirect
-	github.com/google/pprof v0.0.0-20250607225305-033d6d78b36a // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
 	github.com/google/uuid v1.6.0 // indirect
 	github.com/gordonklaus/ineffassign v0.1.0 // indirect
@@ -372,7 +370,6 @@ require (
 	github.com/norwoodj/helm-docs v1.14.2 // indirect
 	github.com/nunnatsa/ginkgolinter v0.20.0 // indirect
 	github.com/oklog/ulid v1.3.1 // indirect
-	github.com/onsi/ginkgo/v2 v2.23.4 // indirect
 	github.com/opencontainers/go-digest v1.0.0 // indirect
 	github.com/opencontainers/image-spec v1.1.1 // indirect
 	github.com/opencontainers/runtime-spec v1.2.1 // indirect
@@ -408,7 +405,7 @@ require (
 	github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect
 	github.com/securego/gosec/v2 v2.22.6 // indirect
 	github.com/segmentio/asm v1.2.0 // indirect
-	github.com/segmentio/encoding v0.5.1 // indirect
+	github.com/segmentio/encoding v0.5.3 // indirect
 	github.com/segmentio/ksuid v1.0.4 // indirect
 	github.com/shirou/gopsutil/v4 v4.25.6 // indirect
 	github.com/sirupsen/logrus v1.9.3 // indirect
@@ -422,7 +419,7 @@ require (
 	github.com/spiffe/go-spiffe/v2 v2.5.0 // indirect
 	github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect
 	github.com/stbenjam/no-sprintf-host-port v0.2.0 // indirect
-	github.com/stoewer/go-strcase v1.3.0 // indirect
+	github.com/stoewer/go-strcase v1.3.1 // indirect
 	github.com/stretchr/objx v0.5.2 // indirect
 	github.com/subosito/gotenv v1.6.0 // indirect
 	github.com/sylabs/sif/v2 v2.21.1 // indirect
@@ -473,8 +470,8 @@ require (
 	go.opencensus.io v0.24.0 // indirect
 	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
 	go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.61.0 // indirect
-	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
-	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 // indirect
+	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 // indirect
+	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect
 	go.opentelemetry.io/otel/trace v1.37.0 // indirect
 	go.uber.org/automaxprocs v1.6.0 // indirect
@@ -494,7 +491,7 @@ require (
 	golang.org/x/time v0.12.0 // indirect
 	golang.org/x/tools v0.35.0 // indirect
 	golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 // indirect
 	google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.5.1 // indirect
 	gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
 	gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
diff --git a/go.sum b/go.sum
index 68fe83334..23672b712 100644
--- a/go.sum
+++ b/go.sum
@@ -4,14 +4,14 @@
 4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
 al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho=
 al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
-buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250121211742-6d880cc6cc8d.1 h1:f6miF8tK6H+Ktad24WpnNfpHO75GRGk0rhJ1mxPXqgA=
-buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250121211742-6d880cc6cc8d.1/go.mod h1:rvbyamNtvJ4o3ExeCmaG5/6iHnu0vy0E+UQ+Ph0om8s=
-buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250613105001-9f2d3c737feb.1 h1:AUL6VF5YWL01j/1H/DQbPUSDkEwYqwVCNw7yhbpOxSQ=
-buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250613105001-9f2d3c737feb.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U=
-buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250606164443-9d1800bf4ccc.1 h1:x7juyChlm/fXZyuJTdBeMzHwAMhPJkP0qE4/IpwpGX4=
-buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250606164443-9d1800bf4ccc.1/go.mod h1:vi8xjh+6SQRvLQYnyVFZ7kOBrFevwFudusxWVc6E58A=
-buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250606164443-9d1800bf4ccc.1 h1:iiP7EL8EWrWmxn9qPDQTFdVSu04qIrmglpyjC10K4IU=
-buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250606164443-9d1800bf4ccc.1/go.mod h1:bUPpZtzAkcnTA7OLfKCvkvkxEAC6dG/ZIlbnbUJicL4=
+buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250718181942-e35f9b667443.1 h1:8kSz6PsTC64z3itQqwMgswSGR/QpB3ShZGycu+zq+58=
+buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go v1.36.6-20250718181942-e35f9b667443.1/go.mod h1:TsmeaGU5CZAF7zRM05vIKgXh56GgwaoMS8X+a77RV5Q=
+buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1 h1:Lg6klmCi3v7VvpqeeLEER9/m5S8y9e9DjhqQnSCNy4k=
+buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.6-20250717185734-6c6e0d3c608e.1/go.mod h1:avRlCjnFzl98VPaeCtJ24RrV/wwHFzB8sWXhj26+n/U=
+buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250721151928-2b7ae473b098.1 h1:icgV8NMRNi31JwLZ8OJQK1HNIX3RTBdhjvpRPJF4fyI=
+buf.build/gen/go/bufbuild/registry/connectrpc/go v1.18.1-20250721151928-2b7ae473b098.1/go.mod h1:/MMEAJmz7PEmksjkSxhWXell82FXiG7BLUPBJRmKBsA=
+buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250721151928-2b7ae473b098.1 h1:fgiFo9f0jCni7kb5QxQ78CccZv6WLTH5Iea2B+AvSKY=
+buf.build/gen/go/bufbuild/registry/protocolbuffers/go v1.36.6-20250721151928-2b7ae473b098.1/go.mod h1:RsJBKYlgzsbl5LAhIu0cNrPPzBNenMLTAAykRxFidtw=
 buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1 h1:trcsXBDm8exui7mvndZnvworCyBq1xuMnod2N0j79K8=
 buf.build/gen/go/pluginrpc/pluginrpc/protocolbuffers/go v1.36.6-20241007202033-cf42259fcbfc.1/go.mod h1:OUbhXurY+VHFGn9FBxcRy8UB7HXk9NvJ2qCgifOMypQ=
 buf.build/go/app v0.1.0 h1:nlqD/h0rhIN73ZoiDElprrPiO2N6JV+RmNK34K29Ihg=
@@ -20,8 +20,8 @@ buf.build/go/bufplugin v0.9.0 h1:ktZJNP3If7ldcWVqh46XKeiYJVPxHQxCfjzVQDzZ/lo=
 buf.build/go/bufplugin v0.9.0/go.mod h1:Z0CxA3sKQ6EPz/Os4kJJneeRO6CjPeidtP1ABh5jPPY=
 buf.build/go/interrupt v1.1.0 h1:olBuhgv9Sav4/9pkSLoxgiOsZDgM5VhRhvRpn3DL0lE=
 buf.build/go/interrupt v1.1.0/go.mod h1:ql56nXPG1oHlvZa6efNC7SKAQ/tUjS6z0mhJl0gyeRM=
-buf.build/go/protovalidate v0.13.1 h1:6loHDTWdY/1qmqmt1MijBIKeN4T9Eajrqb9isT1W1s8=
-buf.build/go/protovalidate v0.13.1/go.mod h1:C/QcOn/CjXRn5udUwYBiLs8y1TGy7RS+GOSKqjS77aU=
+buf.build/go/protovalidate v0.14.0 h1:kr/rC/no+DtRyYX+8KXLDxNnI1rINz0imk5K44ZpZ3A=
+buf.build/go/protovalidate v0.14.0/go.mod h1:+F/oISho9MO7gJQNYC2VWLzcO1fTPmaTA08SDYJZncA=
 buf.build/go/protoyaml v0.6.0 h1:Nzz1lvcXF8YgNZXk+voPPwdU8FjDPTUV4ndNTXN0n2w=
 buf.build/go/protoyaml v0.6.0/go.mod h1:RgUOsBu/GYKLDSIRgQXniXbNgFlGEZnQpRAUdLAFV2Q=
 buf.build/go/spdx v0.2.0 h1:IItqM0/cMxvFJJumcBuP8NrsIzMs/UYjp/6WSpq8LTw=
@@ -176,8 +176,8 @@ github.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDw
 github.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s=
 github.com/bshuster-repo/logrus-logstash-hook v1.0.0 h1:e+C0SB5R1pu//O4MQ3f9cFuPGoOVeF2fE4Og9otCc70=
 github.com/bshuster-repo/logrus-logstash-hook v1.0.0/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
-github.com/bufbuild/buf v1.55.1 h1:yaRXO9YmtgyEhiqT/gwuJWhHN9xBBbqlQvXVnPauvCk=
-github.com/bufbuild/buf v1.55.1/go.mod h1:bvDF6WkvObC+ca9gmP++/oCAWeVVX7MspMcTFznqF7k=
+github.com/bufbuild/buf v1.56.0 h1:Z0eK+npK01FB924rtDVMOJtvBh9c421mYLo9QhUP3pM=
+github.com/bufbuild/buf v1.56.0/go.mod h1:uDNMYshCJIXL99OQc71SDeFiDqOse9sSHXPpZlrqElw=
 github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw=
 github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
 github.com/bufbuild/protoplugin v0.0.0-20250218205857-750e09ce93e1 h1:V1xulAoqLqVg44rY97xOR+mQpD2N+GzhMHVwJ030WEU=
@@ -233,8 +233,8 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
 github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
 github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A=
 github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw=
-github.com/containerd/stargz-snapshotter/estargz v0.16.3 h1:7evrXtoh1mSbGj/pfRccTampEyKpjpOnS3CyiV1Ebr8=
-github.com/containerd/stargz-snapshotter/estargz v0.16.3/go.mod h1:uyr4BfYfOj3G9WBVE8cOlQmXAbPN9VEQpBBeJIuOipU=
+github.com/containerd/stargz-snapshotter/estargz v0.17.0 h1:+TyQIsR/zSFI1Rm31EQBwpAA1ovYgIKHy7kctL3sLcE=
+github.com/containerd/stargz-snapshotter/estargz v0.17.0/go.mod h1:s06tWAiJcXQo9/8AReBCIo/QxcXFZ2n4qfsRnpl71SM=
 github.com/containerd/typeurl/v2 v2.2.3 h1:yNA/94zxWdvYACdYO8zofhrTVuQY73fFU1y++dYSw40=
 github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk=
 github.com/containers/image/v5 v5.36.0 h1:Zh+xFcLjRmicnOT5AFPHH/xj+e3s9ojDN/9X2Kx1+Jo=
@@ -492,8 +492,8 @@ github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e h1:gD6P7NEo7Eqt
 github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e/go.mod h1:h+wZwLjUTJnm/P2rwlbJdRPZXOzaT36/FwnPnY2inzc=
 github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
 github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
-github.com/google/cel-go v0.25.0 h1:jsFw9Fhn+3y2kBbltZR4VEz5xKkcIFRPDnuEzAGv5GY=
-github.com/google/cel-go v0.25.0/go.mod h1:hjEb6r5SuOSlhCHmFoLzu8HGCERvIsDAbxDAyNU/MmI=
+github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI=
+github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM=
 github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
 github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
@@ -718,8 +718,8 @@ github.com/mgechev/revive v1.11.0 h1:b/gLLpBE427o+Xmd8G58gSA+KtBwxWinH/A565Awh0w
 github.com/mgechev/revive v1.11.0/go.mod h1:tI0oLF/2uj+InHCBLrrqfTKfjtFTBCFFfG05auyzgdw=
 github.com/microsoft/go-mssqldb v1.9.2 h1:nY8TmFMQOHpm2qVWo6y4I2mAmVdZqlGiMGAYt64Ibbs=
 github.com/microsoft/go-mssqldb v1.9.2/go.mod h1:GBbW9ASTiDC+mpgWDGKdm3FnFLTUsLYN3iFL90lQ+PA=
-github.com/miekg/dns v1.1.67 h1:kg0EHj0G4bfT5/oOys6HhZw4vmMlnoZ+gDu8tJ/AlI0=
-github.com/miekg/dns v1.1.67/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
+github.com/miekg/dns v1.1.68 h1:jsSRkNozw7G/mnmXULynzMNIsgY2dHC8LO6U6Ij2JEA=
+github.com/miekg/dns v1.1.68/go.mod h1:fujopn7TB3Pu3JM69XaawiU0wqjpL9/8xGop5UrTPps=
 github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
 github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
 github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
@@ -840,8 +840,8 @@ github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY=
 github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg=
 github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
 github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
-github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
-github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
+github.com/prometheus/client_golang v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
+github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
 github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
 github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
@@ -863,8 +863,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4l
 github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
 github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
 github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
-github.com/quic-go/quic-go v0.52.0 h1:/SlHrCRElyaU6MaEPKqKr9z83sBg2v4FLLvWM+Z47pA=
-github.com/quic-go/quic-go v0.52.0/go.mod h1:MFlGGpcpJqRAfmYi6NC2cptDPSxRWTOGNuP4wqrWmzQ=
+github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
+github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
 github.com/raeperd/recvcheck v0.2.0 h1:GnU+NsbiCqdC2XX5+vMZzP+jAJC5fht7rcVTAhX74UI=
 github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU=
 github.com/redis/go-redis/extra/rediscmd/v9 v9.0.5 h1:EaDatTxkdHG+U3Bk4EUr+DZ7fOGwTfezUiUJMaIcaho=
@@ -906,8 +906,8 @@ github.com/securego/gosec/v2 v2.22.6 h1:mixR+X+Z5fT6QddWY8jyU9gs43CyW0SnADHB6kJm
 github.com/securego/gosec/v2 v2.22.6/go.mod h1:510TFNDMrIPytokyHQAVLvPeDr41Yihn2ak8P+XQfNE=
 github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
 github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
-github.com/segmentio/encoding v0.5.1 h1:LhmgXA5/alniiqfc4cYYrxF6DbUQ3m8MVz4/LQIU1mg=
-github.com/segmentio/encoding v0.5.1/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
+github.com/segmentio/encoding v0.5.3 h1:OjMgICtcSFuNvQCdwqMCv9Tg7lEOXGwm1J5RPQccx6w=
+github.com/segmentio/encoding v0.5.3/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0=
 github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
 github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
 github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
@@ -949,8 +949,8 @@ github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YE
 github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
 github.com/stbenjam/no-sprintf-host-port v0.2.0 h1:i8pxvGrt1+4G0czLr/WnmyH7zbZ8Bg8etvARQ1rpyl4=
 github.com/stbenjam/no-sprintf-host-port v0.2.0/go.mod h1:eL0bQ9PasS0hsyTyfTjjG+E80QIyPnBVQbYZyv20Jfk=
-github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs=
-github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
+github.com/stoewer/go-strcase v1.3.1 h1:iS0MdW+kVTxgMoE1LAZyMiYJFKlOzLooE4MxjirtkAs=
+github.com/stoewer/go-strcase v1.3.1/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -1109,8 +1109,8 @@ go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 h1:jmTVJ86dP60C01K3slFQ
 go.opentelemetry.io/contrib/exporters/autoexport v0.57.0/go.mod h1:EJBheUMttD/lABFyLXhce47Wr6DPWYReCzaZiXadH7g=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc=
 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0 h1:Hf9xI/XLML9ElpiHVDNwvqI0hIFlzV8dgIr35kV1kRU=
+go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.62.0/go.mod h1:NfchwuyNoMcZ5MLHwPrODwUF1HWCXWrL31s8gSAdIKY=
 go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
 go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
 go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.8.0 h1:WzNab7hOOLzdDF/EoWCt4glhrbMPVMOO5JYTmpz36Ls=
@@ -1121,8 +1121,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0 h1:zG8
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.37.0/go.mod h1:hOfBCz8kv/wuq73Mx2H2QnWokh/kHZxkh6SNF2bdKtw=
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0 h1:9PgnL3QNlj10uGxExowIDIZu66aVBwWhXmbOp1pa6RA=
 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.37.0/go.mod h1:0ineDcLELf6JmKfuo0wvvhAVMuxWFYvkTin2iV4ydPQ=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0 h1:dNzwXjZKpMpE2JhmO+9HsPl42NIXFIFSUSSs0fiqra0=
-go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.36.0/go.mod h1:90PoxvaEB5n6AOdZvi+yWJQoE95U8Dhhw2bSyRqnTD0=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
+go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA=
 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
@@ -1147,8 +1147,8 @@ go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFh
 go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
 go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
 go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
-go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os=
-go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo=
+go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
+go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
 go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
 go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
 go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
@@ -1175,8 +1175,8 @@ golang.org/x/crypto v0.40.0/go.mod h1:Qr1vMER5WyS2dfPHAlsOj01wgLbsyWtFn/aY+5+Zdx
 golang.org/x/crypto/x509roots/fallback v0.0.0-20250406160420-959f8f3db0fb h1:Iu0p/klM0SM7atONioa/bPhLS7cjhnip99x1OIGibwg=
 golang.org/x/crypto/x509roots/fallback v0.0.0-20250406160420-959f8f3db0fb/go.mod h1:lxN5T34bK4Z/i6cMaU7frUU57VkDXFD4Kamfl/cp9oU=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
-golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4=
-golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
+golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 h1:R9PFI6EUdfVKgwKjZef7QIwGcBKu86OEFpJ9nUEP2l4=
+golang.org/x/exp v0.0.0-20250718183923-645b1fa84792/go.mod h1:A+z0yzpGtvnG90cToK5n2tu8UJVP2XUATh+r+sfOOOc=
 golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
 golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
 golang.org/x/exp/typeparams v0.0.0-20250620022241-b7579e27df2b h1:KdrhdYPDUvJTvrDK9gdjfFd6JTk8vA1WJoldYSi0kHo=
@@ -1330,10 +1330,10 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
 google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY=
-google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
+google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0 h1:0UOBWO4dC+e51ui0NFKSPbkHHiQ4TmrEfEZMLDyRmY8=
+google.golang.org/genproto/googleapis/api v0.0.0-20250728155136-f173205681a0/go.mod h1:8ytArBbtOy2xfht+y2fqKd5DRDJRUQhqbyEnQ4bDChs=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0 h1:MAKi5q709QWfnkkpNQ0M12hYJ1+e8qYVDyowc4U1XZM=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20250728155136-f173205681a0/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A=
 google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
 google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
diff --git a/internal/cmd/server.go b/internal/cmd/server.go
index 6ba9f77b9..c4924d714 100644
--- a/internal/cmd/server.go
+++ b/internal/cmd/server.go
@@ -24,8 +24,7 @@ import (
 	"github.com/envoyproxy/gateway/internal/message"
 	"github.com/envoyproxy/gateway/internal/metrics"
 	providerrunner "github.com/envoyproxy/gateway/internal/provider/runner"
-	xdsserverrunner "github.com/envoyproxy/gateway/internal/xds/server/runner"
-	xdstranslatorrunner "github.com/envoyproxy/gateway/internal/xds/translator/runner"
+	xdsrunner "github.com/envoyproxy/gateway/internal/xds/runner"
 )
 
 type Runner interface {
@@ -138,12 +137,10 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
 		pResources *message.ProviderResources
 		xdsIR      *message.XdsIR
 		infraIR    *message.InfraIR
-		xds        *message.Xds
 	}{
 		pResources: new(message.ProviderResources),
 		xdsIR:      new(message.XdsIR),
 		infraIR:    new(message.InfraIR),
-		xds:        new(message.Xds),
 	}
 
 	// The Elected channel is used to block the tasks that are waiting for the leader to be elected.
@@ -183,13 +180,13 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
 			}),
 		},
 		{
-			// Start the Xds Translator Service
-			// It subscribes to the xdsIR, translates it into xds Resources and publishes it.
+			// Start the Xds Service
+			// It subscribes to the xdsIR, translates it into xds Resources
+			// and publishes it into the xDS Cache.
 			// It also computes the EnvoyPatchPolicy statuses and publishes it.
-			runner: xdstranslatorrunner.New(&xdstranslatorrunner.Config{
+			runner: xdsrunner.New(&xdsrunner.Config{
 				Server:            *cfg,
 				XdsIR:             channels.xdsIR,
-				Xds:               channels.xds,
 				ExtensionManager:  extMgr,
 				ProviderResources: channels.pResources,
 			}),
@@ -203,15 +200,6 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
 				InfraIR: channels.infraIR,
 			}),
 		},
-		{
-			// Start the xDS Server
-			// It subscribes to the xds Resources and configures the remote Envoy Proxy
-			// via the xDS Protocol.
-			runner: xdsserverrunner.New(&xdsserverrunner.Config{
-				Server: *cfg,
-				Xds:    channels.xds,
-			}),
-		},
 		{
 			// Start the Admin Server
 			// It provides admin endpoints including pprof for debugging.
@@ -254,7 +242,6 @@ func startRunners(ctx context.Context, cfg *config.Server) (err error) {
 		channels.pResources,
 		channels.xdsIR,
 		channels.infraIR,
-		channels.xds,
 	}
 	for _, ch := range closeChannels {
 		ch.Close()
diff --git a/internal/message/types.go b/internal/message/types.go
index 5ef6acf21..10c5b5572 100644
--- a/internal/message/types.go
+++ b/internal/message/types.go
@@ -15,7 +15,6 @@ import (
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/gatewayapi/resource"
 	"github.com/envoyproxy/gateway/internal/ir"
-	xdstypes "github.com/envoyproxy/gateway/internal/xds/types"
 )
 
 // ProviderResources message
@@ -133,16 +132,9 @@ type InfraIR struct {
 	watchable.Map[string, *ir.Infra]
 }
 
-// Xds message
-type Xds struct {
-	watchable.Map[string, *xdstypes.ResourceVersionTable]
-}
-
 type MessageName string
 
 const (
-	// XDSMessageName is a message containing xds translated from xds-ir
-	XDSMessageName MessageName = "xds"
 	// XDSIRMessageName is a message containing xds-ir translated from provider-resources
 	XDSIRMessageName MessageName = "xds-ir"
 	// InfraIRMessageName is a message containing infra-ir translated from provider-resources
diff --git a/internal/metrics/register.go b/internal/metrics/register.go
index 51c3f9761..cb1d761be 100644
--- a/internal/metrics/register.go
+++ b/internal/metrics/register.go
@@ -112,9 +112,8 @@ func (r *Runner) newOptions() (registerOptions, error) {
 		newOpts.pullOptions.disable = true
 	} else {
 		newOpts.pullOptions.disable = false
-		restclient.RegisterClientMetricsWithoutRequestTotal(metricsserver.Registry)
-		// Workqueue metrics are already registered in controller-runtime. Use another registry.
 		reg := prometheus.NewRegistry()
+		restclient.RegisterClientMetricsWithoutRequestTotal(reg)
 		workqueue.RegisterMetrics(reg)
 		newOpts.pullOptions.registry = metricsserver.Registry
 		newOpts.pullOptions.gatherer = prometheus.Gatherers{
diff --git a/internal/xds/server/runner/runner.go b/internal/xds/runner/runner.go
similarity index 58%
rename from internal/xds/server/runner/runner.go
rename to internal/xds/runner/runner.go
index df47b9951..7262739ef 100644
--- a/internal/xds/server/runner/runner.go
+++ b/internal/xds/runner/runner.go
@@ -10,6 +10,7 @@ import (
 	"crypto/tls"
 	"fmt"
 	"net"
+	"reflect"
 	"strconv"
 	"time"
 
@@ -25,15 +26,19 @@ import (
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/credentials"
 	"google.golang.org/grpc/keepalive"
+	ktypes "k8s.io/apimachinery/pkg/types"
 
 	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
 	"github.com/envoyproxy/gateway/internal/crypto"
 	"github.com/envoyproxy/gateway/internal/envoygateway/config"
+	extension "github.com/envoyproxy/gateway/internal/extension/types"
+	"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit"
+	"github.com/envoyproxy/gateway/internal/ir"
 	"github.com/envoyproxy/gateway/internal/message"
 	"github.com/envoyproxy/gateway/internal/xds/bootstrap"
 	"github.com/envoyproxy/gateway/internal/xds/cache"
 	"github.com/envoyproxy/gateway/internal/xds/server/kubejwt"
-	xdstypes "github.com/envoyproxy/gateway/internal/xds/types"
+	"github.com/envoyproxy/gateway/internal/xds/translator"
 )
 
 const (
@@ -63,9 +68,15 @@ const (
 
 type Config struct {
 	config.Server
-	Xds   *message.Xds
-	grpc  *grpc.Server
-	cache cache.SnapshotCacheWithCallbacks
+	grpc              *grpc.Server
+	cache             cache.SnapshotCacheWithCallbacks
+	XdsIR             *message.XdsIR
+	ExtensionManager  extension.Manager
+	ProviderResources *message.ProviderResources
+	// Test-configurable TLS paths
+	TLSCertPath string
+	TLSKeyPath  string
+	TLSCaPath   string
 }
 
 type Runner struct {
@@ -77,7 +88,7 @@ func New(cfg *Config) *Runner {
 }
 
 func (r *Runner) Name() string {
-	return string(egv1a1.LogComponentXdsServerRunner)
+	return string(egv1a1.LogComponentXdsRunner)
 }
 
 // Close implements Runner interface.
@@ -141,11 +152,10 @@ func (r *Runner) Start(ctx context.Context) (err error) {
 	// Start and listen xDS gRPC Server.
 	go r.serveXdsServer(ctx)
 
-	// Start message Subscription.
 	// Do not call .Subscribe() inside Goroutine since it is supposed to be called from the same
 	// Goroutine where Close() is called.
-	xdsSubCh := r.Xds.Subscribe(ctx)
-	go r.subscribeAndTranslate(xdsSubCh)
+	sub := r.XdsIR.Subscribe(ctx)
+	go r.subscribeAndTranslate(sub)
 	r.Logger.Info("started")
 	return
 }
@@ -186,51 +196,137 @@ func registerServer(srv serverv3.Server, g *grpc.Server) {
 	runtimev3.RegisterRuntimeDiscoveryServiceServer(g, srv)
 }
 
-func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *xdstypes.ResourceVersionTable]) {
-	message.HandleSubscription(message.Metadata{Runner: r.Name(), Message: message.XDSMessageName}, sub,
-		func(update message.Update[string, *xdstypes.ResourceVersionTable], errChan chan error) {
+func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *ir.Xds]) {
+	// Subscribe to resources
+	message.HandleSubscription(message.Metadata{Runner: r.Name(), Message: message.XDSIRMessageName}, sub,
+		func(update message.Update[string, *ir.Xds], errChan chan error) {
+			r.Logger.Info("received an update")
 			key := update.Key
 			val := update.Value
 
-			r.Logger.Info("received an update")
-			var err error
 			if update.Delete {
-				err = r.cache.GenerateNewSnapshot(key, nil)
-			} else if val != nil && val.XdsResources != nil {
-				if r.cache == nil {
-					r.Logger.Error(err, "failed to init snapshot cache")
+				if err := r.cache.GenerateNewSnapshot(key, nil); err != nil {
+					r.Logger.Error(err, "failed to delete the snapshot")
 					errChan <- err
-				} else {
-					// Update snapshot cache
-					err = r.cache.GenerateNewSnapshot(key, val.XdsResources)
 				}
-			}
-			if err != nil {
-				r.Logger.Error(err, "failed to generate a snapshot")
-				errChan <- err
+			} else {
+				// Translate to xds resources
+				t := &translator.Translator{
+					ControllerNamespace: r.ControllerNamespace,
+					FilterOrder:         val.FilterOrder,
+					RuntimeFlags:        r.EnvoyGateway.RuntimeFlags,
+					Logger:              r.Logger,
+				}
+
+				// Set the extension manager if an extension is loaded
+				if r.ExtensionManager != nil {
+					t.ExtensionManager = &r.ExtensionManager
+				}
+
+				// Set the rate limit service URL if global rate limiting is enabled.
+				if r.EnvoyGateway.RateLimit != nil {
+					t.GlobalRateLimit = &translator.GlobalRateLimitSettings{
+						ServiceURL: ratelimit.GetServiceURL(r.ControllerNamespace, r.DNSDomain),
+						FailClosed: r.EnvoyGateway.RateLimit.FailClosed,
+					}
+					if r.EnvoyGateway.RateLimit.Timeout != nil {
+						t.GlobalRateLimit.Timeout = r.EnvoyGateway.RateLimit.Timeout.Duration
+					}
+				}
+
+				result, err := t.Translate(val)
+				if err != nil {
+					r.Logger.Error(err, "failed to translate xds ir")
+					errChan <- err
+				}
+
+				// xDS translation is done in a best-effort manner, so the result
+				// may contain partial resources even if there are errors.
+				if result == nil {
+					r.Logger.Info("no xds resources to publish")
+					return
+				}
+
+				// Get all status keys from watchable and save them in the map statusesToDelete.
+				// Iterating through result.EnvoyPatchPolicyStatuses, any valid keys will be removed from statusesToDelete.
+				// Remaining keys will be deleted from watchable before we exit this function.
+				statusesToDelete := make(map[ktypes.NamespacedName]bool)
+				for key := range r.ProviderResources.EnvoyPatchPolicyStatuses.LoadAll() {
+					statusesToDelete[key] = true
+				}
+
+				// Publish EnvoyPatchPolicyStatus
+				for _, e := range result.EnvoyPatchPolicyStatuses {
+					key := ktypes.NamespacedName{
+						Name:      e.Name,
+						Namespace: e.Namespace,
+					}
+					// Skip updating status for policies with empty status
+					// They may have been skipped in this translation because
+					// their target is not found (not relevant)
+					if !(reflect.ValueOf(e.Status).IsZero()) {
+						r.ProviderResources.EnvoyPatchPolicyStatuses.Store(key, e.Status)
+					}
+					delete(statusesToDelete, key)
+				}
+				// Discard the EnvoyPatchPolicyStatuses to reduce memory footprint
+				result.EnvoyPatchPolicyStatuses = nil
+
+				// Update snapshot cache
+				if err == nil {
+					if result.XdsResources != nil {
+						if r.cache == nil {
+							r.Logger.Error(err, "failed to init snapshot cache")
+							errChan <- err
+						} else {
+							// Update snapshot cache
+							if err := r.cache.GenerateNewSnapshot(key, result.XdsResources); err != nil {
+								r.Logger.Error(err, "failed to generate a snapshot")
+								errChan <- err
+							}
+						}
+					} else {
+						r.Logger.Error(err, "skipped publishing xds resources")
+					}
+				}
+
+				// Delete all the deletable status keys
+				for key := range statusesToDelete {
+					r.ProviderResources.EnvoyPatchPolicyStatuses.Delete(key)
+				}
 			}
 		},
 	)
-
 	r.Logger.Info("subscriber shutting down")
 }
 
 func (r *Runner) loadTLSConfig() (tlsConfig *tls.Config, err error) {
-	switch {
-	case r.EnvoyGateway.Provider.IsRunningOnKubernetes():
-		tlsConfig, err = crypto.LoadTLSConfig(xdsTLSCertFilepath, xdsTLSKeyFilepath, xdsTLSCaFilepath)
-		if err != nil {
-			return nil, fmt.Errorf("failed to create tls config: %w", err)
-		}
+	var certPath, keyPath, caPath string
 
-	case r.EnvoyGateway.Provider.IsRunningOnHost():
-		tlsConfig, err = crypto.LoadTLSConfig(localTLSCertFilepath, localTLSKeyFilepath, localTLSCaFilepath)
-		if err != nil {
-			return nil, fmt.Errorf("failed to create tls config: %w", err)
+	// Use test-configurable paths if provided
+	if r.TLSCertPath != "" && r.TLSKeyPath != "" && r.TLSCaPath != "" {
+		certPath = r.TLSCertPath
+		keyPath = r.TLSKeyPath
+		caPath = r.TLSCaPath
+	} else {
+		// Use default paths based on provider type
+		switch {
+		case r.EnvoyGateway.Provider.IsRunningOnKubernetes():
+			certPath = xdsTLSCertFilepath
+			keyPath = xdsTLSKeyFilepath
+			caPath = xdsTLSCaFilepath
+		case r.EnvoyGateway.Provider.IsRunningOnHost():
+			certPath = localTLSCertFilepath
+			keyPath = localTLSKeyFilepath
+			caPath = localTLSCaFilepath
+		default:
+			return nil, fmt.Errorf("no valid tls certificates")
 		}
+	}
 
-	default:
-		return nil, fmt.Errorf("no valid tls certificates")
+	tlsConfig, err = crypto.LoadTLSConfig(certPath, keyPath, caPath)
+	if err != nil {
+		return nil, fmt.Errorf("failed to create tls config: %w", err)
 	}
 	return
 }
diff --git a/internal/xds/translator/runner/runner.go b/internal/xds/translator/runner/runner.go
deleted file mode 100644
index 7f9bb2b5d..000000000
--- a/internal/xds/translator/runner/runner.go
+++ /dev/null
@@ -1,151 +0,0 @@
-// Copyright Envoy Gateway Authors
-// SPDX-License-Identifier: Apache-2.0
-// The full text of the Apache license is available in the LICENSE file at
-// the root of the repo.
-
-package runner
-
-import (
-	"context"
-	"reflect"
-
-	"github.com/telepresenceio/watchable"
-	ktypes "k8s.io/apimachinery/pkg/types"
-
-	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
-	"github.com/envoyproxy/gateway/internal/envoygateway/config"
-	extension "github.com/envoyproxy/gateway/internal/extension/types"
-	"github.com/envoyproxy/gateway/internal/infrastructure/kubernetes/ratelimit"
-	"github.com/envoyproxy/gateway/internal/ir"
-	"github.com/envoyproxy/gateway/internal/message"
-	"github.com/envoyproxy/gateway/internal/xds/translator"
-)
-
-type Config struct {
-	config.Server
-	XdsIR             *message.XdsIR
-	Xds               *message.Xds
-	ExtensionManager  extension.Manager
-	ProviderResources *message.ProviderResources
-}
-
-type Runner struct {
-	Config
-}
-
-func New(cfg *Config) *Runner {
-	return &Runner{Config: *cfg}
-}
-
-// Close implements Runner interface.
-func (r *Runner) Close() error { return nil }
-
-// Name implements Runner interface.
-func (r *Runner) Name() string {
-	return string(egv1a1.LogComponentXdsTranslatorRunner)
-}
-
-// Start starts the xds-translator runner
-func (r *Runner) Start(ctx context.Context) (err error) {
-	r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
-	// Do not call .Subscribe() inside Goroutine since it is supposed to be called from the same
-	// Goroutine where Close() is called.
-	sub := r.XdsIR.Subscribe(ctx)
-	go r.subscribeAndTranslate(sub)
-	r.Logger.Info("started")
-	return
-}
-
-func (r *Runner) subscribeAndTranslate(sub <-chan watchable.Snapshot[string, *ir.Xds]) {
-	// Subscribe to resources
-	message.HandleSubscription(message.Metadata{Runner: r.Name(), Message: message.XDSIRMessageName}, sub,
-		func(update message.Update[string, *ir.Xds], errChan chan error) {
-			r.Logger.Info("received an update")
-			key := update.Key
-			val := update.Value
-
-			if update.Delete {
-				r.Xds.Delete(key)
-			} else {
-				// Translate to xds resources
-				t := &translator.Translator{
-					ControllerNamespace: r.ControllerNamespace,
-					FilterOrder:         val.FilterOrder,
-					RuntimeFlags:        r.EnvoyGateway.RuntimeFlags,
-					Logger:              r.Logger,
-				}
-
-				// Set the extension manager if an extension is loaded
-				if r.ExtensionManager != nil {
-					t.ExtensionManager = &r.ExtensionManager
-				}
-
-				// Set the rate limit service URL if global rate limiting is enabled.
-				if r.EnvoyGateway.RateLimit != nil {
-					t.GlobalRateLimit = &translator.GlobalRateLimitSettings{
-						ServiceURL: ratelimit.GetServiceURL(r.ControllerNamespace, r.DNSDomain),
-						FailClosed: r.EnvoyGateway.RateLimit.FailClosed,
-					}
-					if r.EnvoyGateway.RateLimit.Timeout != nil {
-						t.GlobalRateLimit.Timeout = r.EnvoyGateway.RateLimit.Timeout.Duration
-					}
-				}
-
-				result, err := t.Translate(val)
-				if err != nil {
-					r.Logger.Error(err, "failed to translate xds ir")
-					errChan <- err
-				}
-
-				// xDS translation is done in a best-effort manner, so the result
-				// may contain partial resources even if there are errors.
-				if result == nil {
-					r.Logger.Info("no xds resources to publish")
-					return
-				}
-
-				// Get all status keys from watchable and save them in the map statusesToDelete.
-				// Iterating through result.EnvoyPatchPolicyStatuses, any valid keys will be removed from statusesToDelete.
-				// Remaining keys will be deleted from watchable before we exit this function.
-				statusesToDelete := make(map[ktypes.NamespacedName]bool)
-				for key := range r.ProviderResources.EnvoyPatchPolicyStatuses.LoadAll() {
-					statusesToDelete[key] = true
-				}
-
-				// Publish EnvoyPatchPolicyStatus
-				for _, e := range result.EnvoyPatchPolicyStatuses {
-					key := ktypes.NamespacedName{
-						Name:      e.Name,
-						Namespace: e.Namespace,
-					}
-					// Skip updating status for policies with empty status
-					// They may have been skipped in this translation because
-					// their target is not found (not relevant)
-					if !(reflect.ValueOf(e.Status).IsZero()) {
-						r.ProviderResources.EnvoyPatchPolicyStatuses.Store(key, e.Status)
-					}
-					delete(statusesToDelete, key)
-				}
-				// Discard the EnvoyPatchPolicyStatuses to reduce memory footprint
-				result.EnvoyPatchPolicyStatuses = nil
-
-				// Publish
-				if err == nil {
-					r.Xds.Store(key, result)
-					message.PublishMetric(message.Metadata{
-						Runner:  r.Name(),
-						Message: message.XDSMessageName,
-					})
-				} else {
-					r.Logger.Error(err, "skipped publishing xds resources")
-				}
-
-				// Delete all the deletable status keys
-				for key := range statusesToDelete {
-					r.ProviderResources.EnvoyPatchPolicyStatuses.Delete(key)
-				}
-			}
-		},
-	)
-	r.Logger.Info("subscriber shutting down")
-}
diff --git a/internal/xds/types/resourceversiontable.go b/internal/xds/types/resourceversiontable.go
index dc186475b..f6914aa03 100644
--- a/internal/xds/types/resourceversiontable.go
+++ b/internal/xds/types/resourceversiontable.go
@@ -11,7 +11,6 @@ import (
 
 	"github.com/envoyproxy/go-control-plane/pkg/cache/types"
 	resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
-	protobuf "google.golang.org/protobuf/proto"
 
 	"github.com/envoyproxy/gateway/internal/ir"
 	"github.com/envoyproxy/gateway/internal/utils/proto"
@@ -28,45 +27,6 @@ type ResourceVersionTable struct {
 	EnvoyPatchPolicyStatuses
 }
 
-// DeepCopyInto copies the contents into the output object
-// This was generated by controller-gen, moved from
-// zz_generated.deepcopy.go and updated to use proto.Clone
-// to deep copy the proto.Message
-func (t *ResourceVersionTable) DeepCopyInto(out *ResourceVersionTable) {
-	*out = *t
-	if t.XdsResources != nil {
-		in, out := &t.XdsResources, &out.XdsResources
-		*out = make(map[resourcev3.Type][]types.Resource, len(*in))
-		for key, val := range *in {
-			var outVal []types.Resource
-			if val == nil {
-				(*out)[key] = nil
-			} else {
-				// Snippet was generated by controller-gen
-				// G601: Implicit memory aliasing in for loop.
-				in, out := &val, &outVal //nolint:gosec,scopelint
-				*out = make([]types.Resource, len(*in))
-				for i := range *in {
-					(*out)[i] = protobuf.Clone((*in)[i])
-				}
-			}
-			(*out)[key] = outVal
-		}
-	}
-}
-
-// DeepCopy generates a deep copy of the ResourceVersionTable object.
-// This was generated by controller-gen and moved over from
-// zz_generated.deepcopy.go to this file.
-func (t *ResourceVersionTable) DeepCopy() *ResourceVersionTable {
-	if t == nil {
-		return nil
-	}
-	out := new(ResourceVersionTable)
-	t.DeepCopyInto(out)
-	return out
-}
-
 // GetXdsResources retrieves the translated xds resources saved in the translator context.
 func (t *ResourceVersionTable) GetXdsResources() XdsResources {
 	return t.XdsResources
diff --git a/release-notes/current.yaml b/release-notes/current.yaml
index 36bf1fd40..231985117 100644
--- a/release-notes/current.yaml
+++ b/release-notes/current.yaml
@@ -2,6 +2,7 @@ date: Pending
 
 # Changes that are expected to cause an incompatibility with previous versions, such as deletions or modifications to existing APIs.
 breaking changes: |
+  Removed `xds-translator` and `xds-server` values from the `runner` label in `watchable_subscribe_total`. Use `xds` instead
 
 # Updates addressing vulnerabilities, security flaws, or compliance requirements.
 security updates: |
@@ -11,6 +12,7 @@ new features: |
   Added Gateway Listeners to the xDS listener metadata.
 
 bug fixes: |
+  Fixed an issue that controller panic when reloading configuration.
 
 # Enhancements that improve performance.
 performance improvements: |



Test patch:
diff --git a/internal/xds/runner/runner_test.go b/internal/xds/runner/runner_test.go
new file mode 100644
index 000000000..cbcc7fb82
--- /dev/null
+++ b/internal/xds/runner/runner_test.go
@@ -0,0 +1,513 @@
+// Copyright Envoy Gateway Authors
+// SPDX-License-Identifier: Apache-2.0
+// The full text of the Apache license is available in the LICENSE file at
+// the root of the repo.
+
+package runner
+
+import (
+	"context"
+	"crypto/tls"
+	"crypto/x509"
+	"errors"
+	"fmt"
+	"io"
+	"net"
+	"os"
+	"path/filepath"
+	"strconv"
+	"testing"
+	"time"
+
+	listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
+	"github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/require"
+	"github.com/tsaarni/certyaml"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
+	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
+
+	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
+	"github.com/envoyproxy/gateway/internal/crypto"
+	"github.com/envoyproxy/gateway/internal/envoygateway/config"
+	"github.com/envoyproxy/gateway/internal/extension/types"
+	"github.com/envoyproxy/gateway/internal/ir"
+	"github.com/envoyproxy/gateway/internal/message"
+	"github.com/envoyproxy/gateway/internal/xds/bootstrap"
+)
+
+func TestTLSConfig(t *testing.T) {
+	// Create trusted CA, server and client certs.
+	trustedCACert := certyaml.Certificate{
+		Subject: "cn=trusted-ca",
+	}
+	egCertBeforeRotation := certyaml.Certificate{
+		Subject:         "cn=eg-before-rotation",
+		SubjectAltNames: []string{"DNS:localhost"},
+		Issuer:          &trustedCACert,
+	}
+	egCertAfterRotation := certyaml.Certificate{
+		Subject:         "cn=eg-after-rotation",
+		SubjectAltNames: []string{"DNS:localhost"},
+		Issuer:          &trustedCACert,
+	}
+	trustedEnvoyCert := certyaml.Certificate{
+		Subject: "cn=trusted-envoy",
+		Issuer:  &trustedCACert,
+	}
+
+	// Create another CA and a client cert to test that untrusted clients are denied.
+	untrustedCACert := certyaml.Certificate{
+		Subject: "cn=untrusted-ca",
+	}
+	untrustedClientCert := certyaml.Certificate{
+		Subject: "cn=untrusted-client",
+		Issuer:  &untrustedCACert,
+	}
+
+	caCertPool := x509.NewCertPool()
+	ca, err := trustedCACert.X509Certificate()
+	require.NoError(t, err)
+	caCertPool.AddCert(&ca)
+
+	tests := map[string]struct {
+		serverCredentials *certyaml.Certificate
+		clientCredentials *certyaml.Certificate
+		expectError       bool
+	}{
+		"successful TLS connection established": {
+			serverCredentials: &egCertBeforeRotation,
+			clientCredentials: &trustedEnvoyCert,
+			expectError:       false,
+		},
+		"rotating server credentials returns new server cert": {
+			serverCredentials: &egCertAfterRotation,
+			clientCredentials: &trustedEnvoyCert,
+			expectError:       false,
+		},
+		"rotating server credentials again to ensure rotation can be repeated": {
+			serverCredentials: &egCertBeforeRotation,
+			clientCredentials: &trustedEnvoyCert,
+			expectError:       false,
+		},
+		"fail to connect with client certificate which is not signed by correct CA": {
+			serverCredentials: &egCertBeforeRotation,
+			clientCredentials: &untrustedClientCert,
+			expectError:       true,
+		},
+	}
+
+	// Create temporary directory to store certificates and key for the server.
+	configDir, err := os.MkdirTemp("", "eg-testdata-")
+	require.NoError(t, err)
+	defer os.RemoveAll(configDir)
+
+	caFile := filepath.Join(configDir, "ca.crt")
+	certFile := filepath.Join(configDir, "tls.crt")
+	keyFile := filepath.Join(configDir, "tls.key")
+
+	// Initial set of credentials must be written into temp directory before
+	// starting the tests to avoid error at server startup.
+	err = trustedCACert.WritePEM(caFile, keyFile)
+	require.NoError(t, err)
+	err = egCertBeforeRotation.WritePEM(certFile, keyFile)
+	require.NoError(t, err)
+
+	// Start a dummy server.
+	tlsCfg, err := crypto.LoadTLSConfig(certFile, keyFile, caFile)
+	require.NoError(t, err)
+
+	g := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsCfg)))
+	if g == nil {
+		t.Error("failed to create server")
+	}
+
+	address := "localhost:8001"
+	l, err := net.Listen("tcp", address)
+	require.NoError(t, err)
+
+	go func() {
+		err := g.Serve(l)
+		require.NoError(t, err)
+	}()
+	defer g.GracefulStop()
+
+	for name, tc := range tests {
+		t.Run(name, func(t *testing.T) {
+			// Store certificate and key to temp dir used by serveContext.
+			err = tc.serverCredentials.WritePEM(certFile, keyFile)
+			require.NoError(t, err)
+			clientCert, _ := tc.clientCredentials.TLSCertificate()
+			receivedCert, err := tryConnect(address, clientCert, caCertPool)
+			gotError := err != nil
+			if gotError != tc.expectError {
+				t.Errorf("Unexpected result when connecting to the server: %s", err)
+			}
+			if err == nil {
+				expectedCert, _ := tc.serverCredentials.X509Certificate()
+				assert.Equal(t, &expectedCert, receivedCert)
+			}
+		})
+	}
+}
+
+// tryConnect tries to establish TLS connection to the server.
+// If successful, return the server certificate.
+func tryConnect(address string, clientCert tls.Certificate, caCertPool *x509.CertPool) (*x509.Certificate, error) {
+	clientConfig := &tls.Config{
+		ServerName:   "localhost",
+		MinVersion:   tls.VersionTLS13,
+		Certificates: []tls.Certificate{clientCert},
+		NextProtos:   []string{"h2"},
+		RootCAs:      caCertPool,
+	}
+	conn, err := tls.Dial("tcp", address, clientConfig)
+	if err != nil {
+		return nil, err
+	}
+	defer conn.Close()
+
+	err = peekError(conn)
+	if err != nil {
+		return nil, err
+	}
+
+	return conn.ConnectionState().PeerCertificates[0], nil
+}
+
+// peekError is a workaround for TLS 1.3: due to shortened handshake, TLS alert
+// from server is received at first read from the socket. To receive alert for
+// bad certificate, this function tries to read one byte.
+// Adapted from https://golang.org/src/crypto/tls/handshake_client_test.go
+func peekError(conn net.Conn) error {
+	_ = conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
+	_, err := conn.Read(make([]byte, 1))
+	if err != nil {
+		if errors.Is(err, io.EOF) {
+			return nil
+		}
+
+		var netErr net.Error
+		if !errors.As(netErr, &netErr) || !netErr.Timeout() {
+			return err
+		}
+	}
+	return nil
+}
+
+// setupTLSCerts creates temporary TLS certificates for testing
+func setupTLSCerts(t *testing.T) (caFile, certFile, keyFile string, cleanup func()) {
+	configDir, err := os.MkdirTemp("", "eg-runner-test-")
+	require.NoError(t, err)
+
+	caFile = filepath.Join(configDir, "ca.crt")
+	certFile = filepath.Join(configDir, "tls.crt")
+	keyFile = filepath.Join(configDir, "tls.key")
+
+	// Create certificates
+	trustedCACert := certyaml.Certificate{
+		Subject: "cn=test-ca",
+	}
+	serverCert := certyaml.Certificate{
+		Subject:         "cn=test-server",
+		SubjectAltNames: []string{"DNS:localhost"},
+		Issuer:          &trustedCACert,
+	}
+
+	err = trustedCACert.WritePEM(caFile, keyFile)
+	require.NoError(t, err)
+	err = serverCert.WritePEM(certFile, keyFile)
+	require.NoError(t, err)
+
+	return caFile, certFile, keyFile, func() {
+		os.RemoveAll(configDir)
+	}
+}
+
+func TestServeXdsServerListenFailed(t *testing.T) {
+	// Occupy the address to make listening failed
+	addr := net.JoinHostPort(XdsServerAddress, strconv.Itoa(bootstrap.DefaultXdsServerPort))
+	l, err := net.Listen("tcp", addr)
+	require.NoError(t, err)
+	defer l.Close()
+
+	cfg, _ := config.New(os.Stdout)
+	r := New(&Config{
+		Server: *cfg,
+	})
+	r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
+	// Don't crash in this function
+	r.serveXdsServer(context.Background())
+}
+
+func TestRunner(t *testing.T) {
+	// Setup TLS certificates
+	caFile, certFile, keyFile, cleanup := setupTLSCerts(t)
+	defer cleanup()
+
+	// Setup
+	xdsIR := new(message.XdsIR)
+	pResource := new(message.ProviderResources)
+	cfg, err := config.New(os.Stdout)
+	require.NoError(t, err)
+	r := New(&Config{
+		Server:            *cfg,
+		ProviderResources: pResource,
+		XdsIR:             xdsIR,
+		TLSCertPath:       certFile,
+		TLSKeyPath:        keyFile,
+		TLSCaPath:         caFile,
+	})
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	// Start
+	err = r.Start(ctx)
+	require.NoError(t, err)
+	defer func() {
+		cancel()
+		time.Sleep(100 * time.Millisecond) // Allow graceful shutdown
+	}()
+
+	// xDS is nil at start
+	require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
+
+	// test translation
+	path := "example"
+	res := ir.Xds{
+		HTTP: []*ir.HTTPListener{
+			{
+				CoreListenerDetails: ir.CoreListenerDetails{
+					Name:    "test",
+					Address: "0.0.0.0",
+					Port:    80,
+				},
+				Hostnames: []string{"example.com"},
+				Routes: []*ir.HTTPRoute{
+					{
+						Name: "test-route",
+						PathMatch: &ir.StringMatch{
+							Exact: &path,
+						},
+						Destination: &ir.RouteDestination{
+							Name: "test-dest",
+							Settings: []*ir.DestinationSetting{
+								{
+									Endpoints: []*ir.DestinationEndpoint{
+										{
+											Host: "10.11.12.13",
+											Port: 8080,
+										},
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+	xdsIR.Store("test", &res)
+	require.Eventually(t, func() bool {
+		// Check that the cache has the snapshot for our test key
+		return r.cache.SnapshotHasIrKey("test")
+	}, time.Second*5, time.Millisecond*50)
+
+	// Delete the IR triggering an xds delete
+	xdsIR.Delete("test")
+	require.Eventually(t, func() bool {
+		// Wait for the IR to be empty after deletion
+		return len(xdsIR.LoadAll()) == 0
+	}, time.Second*5, time.Millisecond*50)
+}
+
+func TestRunner_withExtensionManager_FailOpen(t *testing.T) {
+	// Setup TLS certificates
+	caFile, certFile, keyFile, cleanup := setupTLSCerts(t)
+	defer cleanup()
+
+	// Setup
+	xdsIR := new(message.XdsIR)
+	pResource := new(message.ProviderResources)
+
+	cfg, err := config.New(os.Stdout)
+	require.NoError(t, err)
+	require.NotNil(t, cfg)
+
+	extMgr := &extManagerMock{}
+	extMgr.ShouldFailOpen = true
+
+	r := New(&Config{
+		Server:            *cfg,
+		ProviderResources: pResource,
+		XdsIR:             xdsIR,
+		ExtensionManager:  extMgr,
+		TLSCertPath:       certFile,
+		TLSKeyPath:        keyFile,
+		TLSCaPath:         caFile,
+	})
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	// Start
+	err = r.Start(ctx)
+	require.NoError(t, err)
+	defer func() {
+		cancel()
+		time.Sleep(100 * time.Millisecond) // Allow graceful shutdown
+	}()
+
+	// xDS is nil at start
+	require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
+
+	// test translation
+	path := "example"
+	res := ir.Xds{
+		HTTP: []*ir.HTTPListener{
+			{
+				CoreListenerDetails: ir.CoreListenerDetails{
+					Name:    "test",
+					Address: "0.0.0.0",
+					Port:    80,
+				},
+				Hostnames: []string{"example.com"},
+				Routes: []*ir.HTTPRoute{
+					{
+						Name: "test-route",
+						PathMatch: &ir.StringMatch{
+							Exact: &path,
+						},
+						Destination: &ir.RouteDestination{
+							Name: "test-dest",
+							Settings: []*ir.DestinationSetting{
+								{
+									Endpoints: []*ir.DestinationEndpoint{
+										{
+											Host: "10.11.12.13",
+											Port: 8080,
+										},
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+	xdsIR.Store("test", &res)
+	require.Eventually(t, func() bool {
+		// Since the extension manager is configured to fail open, in an event of an error
+		// from the extension manager hooks, xds update should be published.
+		return r.cache.SnapshotHasIrKey("test")
+	}, time.Second*5, time.Millisecond*50)
+}
+
+func TestRunner_withExtensionManager_FailClosed(t *testing.T) {
+	// Setup TLS certificates
+	caFile, certFile, keyFile, cleanup := setupTLSCerts(t)
+	defer cleanup()
+
+	// Setup
+	xdsIR := new(message.XdsIR)
+	pResource := new(message.ProviderResources)
+
+	cfg, err := config.New(os.Stdout)
+	require.NoError(t, err)
+	require.NotNil(t, cfg)
+
+	extMgr := &extManagerMock{}
+
+	r := New(&Config{
+		Server:            *cfg,
+		ProviderResources: pResource,
+		XdsIR:             xdsIR,
+		ExtensionManager:  extMgr,
+		TLSCertPath:       certFile,
+		TLSKeyPath:        keyFile,
+		TLSCaPath:         caFile,
+	})
+
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	// Start
+	err = r.Start(ctx)
+	require.NoError(t, err)
+	defer func() {
+		cancel()
+		time.Sleep(100 * time.Millisecond) // Allow graceful shutdown
+	}()
+
+	// xDS is nil at start
+	require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
+
+	// test translation
+	path := "example"
+	res := ir.Xds{
+		HTTP: []*ir.HTTPListener{
+			{
+				CoreListenerDetails: ir.CoreListenerDetails{
+					Name:    "test",
+					Address: "0.0.0.0",
+					Port:    80,
+				},
+				Hostnames: []string{"example.com"},
+				Routes: []*ir.HTTPRoute{
+					{
+						Name: "test-route",
+						PathMatch: &ir.StringMatch{
+							Exact: &path,
+						},
+						Destination: &ir.RouteDestination{
+							Name: "test-dest",
+							Settings: []*ir.DestinationSetting{
+								{
+									Endpoints: []*ir.DestinationEndpoint{
+										{
+											Host: "10.11.12.13",
+											Port: 8080,
+										},
+									},
+								},
+							},
+						},
+					},
+				},
+			},
+		},
+	}
+	xdsIR.Store("test", &res)
+	require.Never(t, func() bool {
+		// Since the extension manager is configured to fail closed, in an event of an error
+		// from the extension manager hooks, xds update should not be published.
+		return r.cache.SnapshotHasIrKey("test")
+	}, time.Second*5, time.Millisecond*50)
+}
+
+type extManagerMock struct {
+	types.Manager
+	ShouldFailOpen bool
+}
+
+func (m *extManagerMock) GetPostXDSHookClient(xdsHookType egv1a1.XDSTranslatorHook) (types.XDSHookClient, error) {
+	if xdsHookType == egv1a1.XDSHTTPListener {
+		return &xdsHookClientMock{}, nil
+	}
+
+	return nil, nil
+}
+
+func (m *extManagerMock) FailOpen() bool {
+	return m.ShouldFailOpen
+}
+
+type xdsHookClientMock struct {
+	types.XDSHookClient
+}
+
+func (c *xdsHookClientMock) PostHTTPListenerModifyHook(*listenerv3.Listener, []*unstructured.Unstructured) (*listenerv3.Listener, error) {
+	return nil, fmt.Errorf("assuming a network error during the call")
+}
diff --git a/internal/xds/server/runner/runner_test.go b/internal/xds/server/runner/runner_test.go
deleted file mode 100644
index 69dd798b8..000000000
--- a/internal/xds/server/runner/runner_test.go
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright Envoy Gateway Authors
-// SPDX-License-Identifier: Apache-2.0
-// The full text of the Apache license is available in the LICENSE file at
-// the root of the repo.
-
-package runner
-
-import (
-	"context"
-	"crypto/tls"
-	"crypto/x509"
-	"errors"
-	"io"
-	"net"
-	"os"
-	"path/filepath"
-	"strconv"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	"github.com/tsaarni/certyaml"
-	"google.golang.org/grpc"
-	"google.golang.org/grpc/credentials"
-
-	"github.com/envoyproxy/gateway/internal/crypto"
-	"github.com/envoyproxy/gateway/internal/envoygateway/config"
-	"github.com/envoyproxy/gateway/internal/xds/bootstrap"
-)
-
-func TestTLSConfig(t *testing.T) {
-	// Create trusted CA, server and client certs.
-	trustedCACert := certyaml.Certificate{
-		Subject: "cn=trusted-ca",
-	}
-	egCertBeforeRotation := certyaml.Certificate{
-		Subject:         "cn=eg-before-rotation",
-		SubjectAltNames: []string{"DNS:localhost"},
-		Issuer:          &trustedCACert,
-	}
-	egCertAfterRotation := certyaml.Certificate{
-		Subject:         "cn=eg-after-rotation",
-		SubjectAltNames: []string{"DNS:localhost"},
-		Issuer:          &trustedCACert,
-	}
-	trustedEnvoyCert := certyaml.Certificate{
-		Subject: "cn=trusted-envoy",
-		Issuer:  &trustedCACert,
-	}
-
-	// Create another CA and a client cert to test that untrusted clients are denied.
-	untrustedCACert := certyaml.Certificate{
-		Subject: "cn=untrusted-ca",
-	}
-	untrustedClientCert := certyaml.Certificate{
-		Subject: "cn=untrusted-client",
-		Issuer:  &untrustedCACert,
-	}
-
-	caCertPool := x509.NewCertPool()
-	ca, err := trustedCACert.X509Certificate()
-	require.NoError(t, err)
-	caCertPool.AddCert(&ca)
-
-	tests := map[string]struct {
-		serverCredentials *certyaml.Certificate
-		clientCredentials *certyaml.Certificate
-		expectError       bool
-	}{
-		"successful TLS connection established": {
-			serverCredentials: &egCertBeforeRotation,
-			clientCredentials: &trustedEnvoyCert,
-			expectError:       false,
-		},
-		"rotating server credentials returns new server cert": {
-			serverCredentials: &egCertAfterRotation,
-			clientCredentials: &trustedEnvoyCert,
-			expectError:       false,
-		},
-		"rotating server credentials again to ensure rotation can be repeated": {
-			serverCredentials: &egCertBeforeRotation,
-			clientCredentials: &trustedEnvoyCert,
-			expectError:       false,
-		},
-		"fail to connect with client certificate which is not signed by correct CA": {
-			serverCredentials: &egCertBeforeRotation,
-			clientCredentials: &untrustedClientCert,
-			expectError:       true,
-		},
-	}
-
-	// Create temporary directory to store certificates and key for the server.
-	configDir, err := os.MkdirTemp("", "eg-testdata-")
-	require.NoError(t, err)
-	defer os.RemoveAll(configDir)
-
-	caFile := filepath.Join(configDir, "ca.crt")
-	certFile := filepath.Join(configDir, "tls.crt")
-	keyFile := filepath.Join(configDir, "tls.key")
-
-	// Initial set of credentials must be written into temp directory before
-	// starting the tests to avoid error at server startup.
-	err = trustedCACert.WritePEM(caFile, keyFile)
-	require.NoError(t, err)
-	err = egCertBeforeRotation.WritePEM(certFile, keyFile)
-	require.NoError(t, err)
-
-	// Start a dummy server.
-	tlsCfg, err := crypto.LoadTLSConfig(certFile, keyFile, caFile)
-	require.NoError(t, err)
-
-	g := grpc.NewServer(grpc.Creds(credentials.NewTLS(tlsCfg)))
-	if g == nil {
-		t.Error("failed to create server")
-	}
-
-	address := "localhost:8001"
-	l, err := net.Listen("tcp", address)
-	require.NoError(t, err)
-
-	go func() {
-		err := g.Serve(l)
-		require.NoError(t, err)
-	}()
-	defer g.GracefulStop()
-
-	for name, tc := range tests {
-		t.Run(name, func(t *testing.T) {
-			// Store certificate and key to temp dir used by serveContext.
-			err = tc.serverCredentials.WritePEM(certFile, keyFile)
-			require.NoError(t, err)
-			clientCert, _ := tc.clientCredentials.TLSCertificate()
-			receivedCert, err := tryConnect(address, clientCert, caCertPool)
-			gotError := err != nil
-			if gotError != tc.expectError {
-				t.Errorf("Unexpected result when connecting to the server: %s", err)
-			}
-			if err == nil {
-				expectedCert, _ := tc.serverCredentials.X509Certificate()
-				assert.Equal(t, &expectedCert, receivedCert)
-			}
-		})
-	}
-}
-
-// tryConnect tries to establish TLS connection to the server.
-// If successful, return the server certificate.
-func tryConnect(address string, clientCert tls.Certificate, caCertPool *x509.CertPool) (*x509.Certificate, error) {
-	clientConfig := &tls.Config{
-		ServerName:   "localhost",
-		MinVersion:   tls.VersionTLS13,
-		Certificates: []tls.Certificate{clientCert},
-		NextProtos:   []string{"h2"},
-		RootCAs:      caCertPool,
-	}
-	conn, err := tls.Dial("tcp", address, clientConfig)
-	if err != nil {
-		return nil, err
-	}
-	defer conn.Close()
-
-	err = peekError(conn)
-	if err != nil {
-		return nil, err
-	}
-
-	return conn.ConnectionState().PeerCertificates[0], nil
-}
-
-// peekError is a workaround for TLS 1.3: due to shortened handshake, TLS alert
-// from server is received at first read from the socket. To receive alert for
-// bad certificate, this function tries to read one byte.
-// Adapted from https://golang.org/src/crypto/tls/handshake_client_test.go
-func peekError(conn net.Conn) error {
-	_ = conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
-	_, err := conn.Read(make([]byte, 1))
-	if err != nil {
-		if errors.Is(err, io.EOF) {
-			return nil
-		}
-
-		var netErr net.Error
-		if !errors.As(netErr, &netErr) || !netErr.Timeout() {
-			return err
-		}
-	}
-	return nil
-}
-
-func TestServeXdsServerListenFailed(t *testing.T) {
-	// Occupy the address to make listening failed
-	addr := net.JoinHostPort(XdsServerAddress, strconv.Itoa(bootstrap.DefaultXdsServerPort))
-	l, err := net.Listen("tcp", addr)
-	require.NoError(t, err)
-	defer l.Close()
-
-	cfg, _ := config.New(os.Stdout)
-	r := New(&Config{
-		Server: *cfg,
-	})
-	r.Logger = r.Logger.WithName(r.Name()).WithValues("runner", r.Name())
-	// Don't crash in this function
-	r.serveXdsServer(context.Background())
-}
diff --git a/internal/xds/translator/runner/runner_test.go b/internal/xds/translator/runner/runner_test.go
deleted file mode 100644
index 45f3f46bf..000000000
--- a/internal/xds/translator/runner/runner_test.go
+++ /dev/null
@@ -1,274 +0,0 @@
-// Copyright Envoy Gateway Authors
-// SPDX-License-Identifier: Apache-2.0
-// The full text of the Apache license is available in the LICENSE file at
-// the root of the repo.
-
-package runner
-
-import (
-	"context"
-	"fmt"
-	"os"
-	"testing"
-	"time"
-
-	listenerv3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3"
-	resourcev3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3"
-	"github.com/stretchr/testify/require"
-	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
-
-	egv1a1 "github.com/envoyproxy/gateway/api/v1alpha1"
-	"github.com/envoyproxy/gateway/internal/envoygateway/config"
-	"github.com/envoyproxy/gateway/internal/extension/types"
-	"github.com/envoyproxy/gateway/internal/ir"
-	"github.com/envoyproxy/gateway/internal/message"
-)
-
-func TestRunner(t *testing.T) {
-	// Setup
-	xdsIR := new(message.XdsIR)
-	xds := new(message.Xds)
-	pResource := new(message.ProviderResources)
-	cfg, err := config.New(os.Stdout)
-	require.NoError(t, err)
-	r := New(&Config{
-		Server:            *cfg,
-		ProviderResources: pResource,
-		XdsIR:             xdsIR,
-		Xds:               xds,
-	})
-
-	ctx := context.Background()
-	// Start
-	err = r.Start(ctx)
-	require.NoError(t, err)
-
-	// xDS is nil at start
-	require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
-
-	// test translation
-	path := "example"
-	res := ir.Xds{
-		HTTP: []*ir.HTTPListener{
-			{
-				CoreListenerDetails: ir.CoreListenerDetails{
-					Name:    "test",
-					Address: "0.0.0.0",
-					Port:    80,
-				},
-				Hostnames: []string{"example.com"},
-				Routes: []*ir.HTTPRoute{
-					{
-						Name: "test-route",
-						PathMatch: &ir.StringMatch{
-							Exact: &path,
-						},
-						Destination: &ir.RouteDestination{
-							Name: "test-dest",
-							Settings: []*ir.DestinationSetting{
-								{
-									Endpoints: []*ir.DestinationEndpoint{
-										{
-											Host: "10.11.12.13",
-											Port: 8080,
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	xdsIR.Store("test", &res)
-	require.Eventually(t, func() bool {
-		out := xds.LoadAll()
-		if out == nil {
-			return false
-		}
-		if out["test"] == nil {
-			return false
-		}
-		// Ensure an xds listener is created
-		return len(out["test"].XdsResources[resourcev3.ListenerType]) == 1
-	}, time.Second*5, time.Millisecond*50)
-
-	// Delete the IR triggering an xds delete
-	xdsIR.Delete("test")
-	require.Eventually(t, func() bool {
-		out := xds.LoadAll()
-		// Ensure that xds has no key, value pairs
-		return len(out) == 0
-	}, time.Second*5, time.Millisecond*50)
-}
-
-func TestRunner_withExtensionManager_FailOpen(t *testing.T) {
-	// Setup
-	xdsIR := new(message.XdsIR)
-	xds := new(message.Xds)
-	pResource := new(message.ProviderResources)
-
-	cfg, err := config.New(os.Stdout)
-	require.NoError(t, err)
-	require.NotNil(t, cfg)
-
-	extMgr := &extManagerMock{}
-	extMgr.ShouldFailOpen = true
-
-	r := New(&Config{
-		Server:            *cfg,
-		ProviderResources: pResource,
-		XdsIR:             xdsIR,
-		Xds:               xds,
-		ExtensionManager:  extMgr,
-	})
-
-	ctx := context.Background()
-	// Start
-	err = r.Start(ctx)
-	require.NoError(t, err)
-
-	// xDS is nil at start
-	require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
-
-	// test translation
-	path := "example"
-	res := ir.Xds{
-		HTTP: []*ir.HTTPListener{
-			{
-				CoreListenerDetails: ir.CoreListenerDetails{
-					Name:    "test",
-					Address: "0.0.0.0",
-					Port:    80,
-				},
-				Hostnames: []string{"example.com"},
-				Routes: []*ir.HTTPRoute{
-					{
-						Name: "test-route",
-						PathMatch: &ir.StringMatch{
-							Exact: &path,
-						},
-						Destination: &ir.RouteDestination{
-							Name: "test-dest",
-							Settings: []*ir.DestinationSetting{
-								{
-									Endpoints: []*ir.DestinationEndpoint{
-										{
-											Host: "10.11.12.13",
-											Port: 8080,
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	xdsIR.Store("test", &res)
-	require.Eventually(t, func() bool {
-		out := xds.LoadAll()
-		// Since the extension manager is configured to fail open, in an event of an error
-		// from the extension manager hooks, xds update should be published.
-		return len(out) == 1
-	}, time.Second*5, time.Millisecond*50)
-}
-
-func TestRunner_withExtensionManager_FailClosed(t *testing.T) {
-	// Setup
-	xdsIR := new(message.XdsIR)
-	xds := new(message.Xds)
-	pResource := new(message.ProviderResources)
-
-	cfg, err := config.New(os.Stdout)
-	require.NoError(t, err)
-	require.NotNil(t, cfg)
-
-	extMgr := &extManagerMock{}
-
-	r := New(&Config{
-		Server:            *cfg,
-		ProviderResources: pResource,
-		XdsIR:             xdsIR,
-		Xds:               xds,
-		ExtensionManager:  extMgr,
-	})
-
-	ctx := context.Background()
-	// Start
-	err = r.Start(ctx)
-	require.NoError(t, err)
-
-	// xDS is nil at start
-	require.Equal(t, map[string]*ir.Xds{}, xdsIR.LoadAll())
-
-	// test translation
-	path := "example"
-	res := ir.Xds{
-		HTTP: []*ir.HTTPListener{
-			{
-				CoreListenerDetails: ir.CoreListenerDetails{
-					Name:    "test",
-					Address: "0.0.0.0",
-					Port:    80,
-				},
-				Hostnames: []string{"example.com"},
-				Routes: []*ir.HTTPRoute{
-					{
-						Name: "test-route",
-						PathMatch: &ir.StringMatch{
-							Exact: &path,
-						},
-						Destination: &ir.RouteDestination{
-							Name: "test-dest",
-							Settings: []*ir.DestinationSetting{
-								{
-									Endpoints: []*ir.DestinationEndpoint{
-										{
-											Host: "10.11.12.13",
-											Port: 8080,
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	}
-	xdsIR.Store("test", &res)
-	require.Never(t, func() bool {
-		out := xds.LoadAll()
-		// Since the extension manager is configured to fail closed,  in an event of an error
-		// from the extension manager hooks, xds update should not be published.
-		return len(out) > 0
-	}, time.Second*5, time.Millisecond*50)
-}
-
-type extManagerMock struct {
-	types.Manager
-	ShouldFailOpen bool
-}
-
-func (m *extManagerMock) GetPostXDSHookClient(xdsHookType egv1a1.XDSTranslatorHook) (types.XDSHookClient, error) {
-	if xdsHookType == egv1a1.XDSHTTPListener {
-		return &xdsHookClientMock{}, nil
-	}
-
-	return nil, nil
-}
-
-func (m *extManagerMock) FailOpen() bool {
-	return m.ShouldFailOpen
-}
-
-type xdsHookClientMock struct {
-	types.XDSHookClient
-}
-
-func (c *xdsHookClientMock) PostHTTPListenerModifyHook(*listenerv3.Listener, []*unstructured.Unstructured) (*listenerv3.Listener, error) {
-	return nil, fmt.Errorf("assuming a network error during the call")
-}
diff --git a/internal/xds/types/resourceversiontable_test.go b/internal/xds/types/resourceversiontable_test.go
index 5fd7a42dd..6f9032dff 100644
--- a/internal/xds/types/resourceversiontable_test.go
+++ b/internal/xds/types/resourceversiontable_test.go
@@ -21,65 +21,8 @@ import (
 	"google.golang.org/protobuf/testing/protocmp"
 )
 
-var (
-	testListener = &listenerv3.Listener{
-		Name: "test-listener",
-	}
-	testSecret = &tlsv3.Secret{
-		Name: "test-secret",
-	}
-)
-
-func TestDeepCopy(t *testing.T) {
-	testCases := []struct {
-		name string
-		in   *ResourceVersionTable
-		out  *ResourceVersionTable
-	}{
-		{
-			name: "nil",
-			in:   nil,
-			out:  nil,
-		},
-		{
-			name: "listener",
-			in: &ResourceVersionTable{
-				XdsResources: XdsResources{
-					resourcev3.ListenerType: []types.Resource{testListener},
-				},
-			},
-			out: &ResourceVersionTable{
-				XdsResources: XdsResources{
-					resourcev3.ListenerType: []types.Resource{testListener},
-				},
-			},
-		},
-		{
-			name: "kitchen-sink",
-			in: &ResourceVersionTable{
-				XdsResources: XdsResources{
-					resourcev3.ListenerType: []types.Resource{testListener},
-					resourcev3.SecretType:   []types.Resource{testSecret},
-				},
-			},
-			out: &ResourceVersionTable{
-				XdsResources: XdsResources{
-					resourcev3.ListenerType: []types.Resource{testListener},
-					resourcev3.SecretType:   []types.Resource{testSecret},
-				},
-			},
-		},
-	}
-	for _, tc := range testCases {
-		t.Run(tc.name, func(t *testing.T) {
-			if tc.out == nil {
-				require.Nil(t, tc.in.DeepCopy())
-			} else {
-				diff := cmp.Diff(tc.out, tc.in.DeepCopy(), protocmp.Transform())
-				require.Empty(t, diff)
-			}
-		})
-	}
+var testListener = &listenerv3.Listener{
+	Name: "test-listener",
 }
 
 func TestAddOrReplaceXdsResource(t *testing.T) {
@@ -533,7 +476,7 @@ func TestAddOrReplaceXdsResource(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			err := tc.tableIn.AddOrReplaceXdsResource(tc.typeIn, tc.resourceIn, tc.funcIn)
 			require.NoError(t, err)
-			diff := cmp.Diff(tc.tableOut, tc.tableIn.DeepCopy(), protocmp.Transform())
+			diff := cmp.Diff(tc.tableOut, tc.tableIn, protocmp.Transform())
 			require.Empty(t, diff)
 		})
 	}
diff --git a/site/content/en/latest/api/extension_types.md b/site/content/en/latest/api/extension_types.md
index f9354b3d3..f981a65bb 100644
--- a/site/content/en/latest/api/extension_types.md
+++ b/site/content/en/latest/api/extension_types.md
@@ -1380,6 +1380,7 @@ _Appears in:_
 | `gateway-api` | LogComponentGatewayAPIRunner defines the "gateway-api" runner component.<br /> | 
 | `xds-translator` | LogComponentXdsTranslatorRunner defines the "xds-translator" runner component.<br /> | 
 | `xds-server` | LogComponentXdsServerRunner defines the "xds-server" runner component.<br /> | 
+| `xds` | LogComponentXdsRunner defines the "xds" runner component.<br /> | 
 | `infrastructure` | LogComponentInfrastructureRunner defines the "infrastructure" runner component.<br /> | 
 | `global-ratelimit` | LogComponentGlobalRateLimitRunner defines the "global-ratelimit" runner component.<br /> | 
 
diff --git a/test/resilience/tests/extensionserver.go b/test/resilience/tests/extensionserver.go
index 6947a87ab..65c4bffeb 100644
--- a/test/resilience/tests/extensionserver.go
+++ b/test/resilience/tests/extensionserver.go
@@ -34,7 +34,7 @@ var ESResilience = suite.ResilienceTest{
 	Test: func(t *testing.T, suite *suite.ResilienceTestSuite) {
 		const (
 			namespace                              = "envoy-gateway-system"
-			PrometheusXDSTranslatorErrors          = `watchable_subscribe_total{runner="xds-translator", status="failure"}`
+			PrometheusXDSTranslatorErrors          = `watchable_subscribe_total{runner="xds", status="failure"}`
 			PrometheusEnvoyConnectedToControlPlane = `envoy_control_plane_connected_state`
 		)