Repository: kubernetes-sigs/gateway-api-inference-extension

Issue:
Align 002-api-proposal with current api/v1alpha2 Go Type Definitions
The `gateway-api-inference-extension/docs/proposals/002-api-proposal/` document is currently outdated and contains discrepancies when compared to the actual Go type definitions in `api/v1alpha2/inferencepool_types.go` and `api/v1alpha2/inferencemodel_types.go`.

This misalignment can lead to:
* Confusion for developers implementing based on the proposal.
* Incorrect assumptions in YAML manifests.
* Challenges in developing and running conformance tests that rely on the proposal's specifications. (see #766)

### Action Required:

Update the `gateway-api-inference-extension/docs/proposals/002-api-proposal/` document to accurately reflect the API details defined in:
* `api/v1alpha2/inferencepool_types.go`
* `api/v1alpha2/inferencemodel_types.go`

This will ensure consistency between the documentation and the codebase, improving clarity and usability for contributors and users.

Discussion:

Solution patch:
diff --git a/conformance/conformance.go b/conformance/conformance.go
index 4cff6bb..66b8c09 100644
--- a/conformance/conformance.go
+++ b/conformance/conformance.go
@@ -77,10 +77,18 @@ const (
 // Future profiles will cover EPP and ModelServer layers.
 const GatewayLayerProfileName confsuite.ConformanceProfileName = "Gateway"
 
+// TODO(#863) Create a dedicated share location for feature names similar to
+// sigs.k8s.io/gateway-api/pkg/features and change the tests from
+// string casting the feature name to referencing the shared feature names.
+
+// Conformance specific features
+const SupportInferencePool features.FeatureName = "SupportInferencePool"
+
 // InferenceCoreFeatures defines the core features that implementations
 // of the "Gateway" profile for the Inference Extension MUST support.
 var InferenceCoreFeatures = sets.New(
 	features.SupportGateway, // This is needed to ensure manifest gets applied during setup.
+	SupportInferencePool,
 )
 
 var GatewayLayerProfile = confsuite.ConformanceProfile{
diff --git a/conformance/resources/manifests/manifests.yaml b/conformance/resources/manifests/manifests.yaml
index 190a884..b2ca489 100644
--- a/conformance/resources/manifests/manifests.yaml
+++ b/conformance/resources/manifests/manifests.yaml
@@ -23,7 +23,7 @@ metadata:
     gateway-conformance: backend
 
 ---
-# Namespace for simple web server backends. This is expected by 
+# Namespace for simple web server backends. This is expected by
 # the upstream conformance suite's Setup method.
 apiVersion: v1
 kind: Namespace
@@ -50,8 +50,27 @@ spec:
     protocol: HTTP
     allowedRoutes:
       namespaces:
-        from: All 
+        from: All
       kinds:
       # Allows HTTPRoutes to attach, which can then reference InferencePools.
       - group: gateway.networking.k8s.io
         kind: HTTPRoute
+
+---
+# --- Conformance Secondary Gateway Definition ---
+# A second generic Gateway resource for tests requiring multiple Gateways.
+apiVersion: gateway.networking.k8s.io/v1
+kind: Gateway
+metadata:
+  name: conformance-secondary-gateway
+  namespace: gateway-conformance-infra
+spec:
+  gatewayClassName: "{GATEWAY_CLASS_NAME}"
+  listeners:
+  - name: http
+    port: 80
+    protocol: HTTP
+    hostname: "secondary.example.com" # Distinct hostname to differentiate from conformance-gateway
+    allowedRoutes:
+      namespaces:
+        from: All
diff --git a/conformance/utils/kubernetes/helpers.go b/conformance/utils/kubernetes/helpers.go
index fbe24b5..a862cfb 100644
--- a/conformance/utils/kubernetes/helpers.go
+++ b/conformance/utils/kubernetes/helpers.go
@@ -34,8 +34,12 @@ import (
 	// Import the Inference Extension API types
 	inferenceapi "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2" // Adjust if your API version is different
 
-	// Import necessary utilities from the core Gateway API conformance suite
+	// Import local config for Inference Extension
 	"sigs.k8s.io/gateway-api-inference-extension/conformance/utils/config"
+	// Import necessary utilities from the core Gateway API conformance suite
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
+	gatewayapiconfig "sigs.k8s.io/gateway-api/conformance/utils/config"
+	gatewayk8sutils "sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
 )
 
 // checkCondition is a helper function similar to findConditionInList or CheckCondition
@@ -152,3 +156,103 @@ func InferencePoolMustHaveCondition(t *testing.T, c client.Client, poolNN types.
 	}
 	t.Log(logMsg)
 }
+
+// InferencePoolMustHaveNoParents waits for the specified InferencePool resource
+// to exist and report that it has no parent references in its status.
+// This typically indicates it is no longer referenced by any Gateway API resources.
+func InferencePoolMustHaveNoParents(t *testing.T, c client.Client, poolNN types.NamespacedName) {
+	t.Helper()
+
+	var lastObservedPool *inferenceapi.InferencePool
+	var lastError error
+	var timeoutConfig config.InferenceExtensionTimeoutConfig = config.DefaultInferenceExtensionTimeoutConfig()
+
+	ctx := context.Background()
+	waitErr := wait.PollUntilContextTimeout(
+		ctx,
+
+		timeoutConfig.InferencePoolMustHaveConditionInterval,
+		timeoutConfig.InferencePoolMustHaveConditionTimeout,
+		true,
+		func(pollCtx context.Context) (bool, error) {
+			pool := &inferenceapi.InferencePool{}
+			err := c.Get(pollCtx, poolNN, pool)
+			if err != nil {
+				if apierrors.IsNotFound(err) {
+					t.Logf("InferencePool %s not found. Considering this as having no parents.", poolNN.String())
+					lastError = nil
+					return true, nil
+				}
+				t.Logf("Error fetching InferencePool %s: %v. Retrying.", poolNN.String(), err)
+				lastError = err
+				return false, nil
+			}
+			lastObservedPool = pool
+			lastError = nil
+
+			if len(pool.Status.Parents) == 0 {
+				t.Logf("InferencePool %s successfully has no parent statuses.", poolNN.String())
+				return true, nil
+			}
+			t.Logf("InferencePool %s still has %d parent statuses. Waiting...", poolNN.String(), len(pool.Status.Parents))
+			return false, nil
+		})
+
+	if waitErr != nil {
+		debugMsg := fmt.Sprintf("Timed out waiting for InferencePool %s to have no parent statuses.", poolNN.String())
+		if lastError != nil {
+			debugMsg += fmt.Sprintf(" Last error during fetching: %v.", lastError)
+		}
+		if lastObservedPool != nil && len(lastObservedPool.Status.Parents) > 0 {
+			debugMsg += fmt.Sprintf(" Last observed InferencePool still had %d parent(s):", len(lastObservedPool.Status.Parents))
+		} else if lastError == nil && (lastObservedPool == nil || len(lastObservedPool.Status.Parents) == 0) {
+			debugMsg += " Polling completed without timeout, but an unexpected waitErr occurred."
+		}
+		require.FailNow(t, debugMsg, waitErr)
+	}
+	t.Logf("Successfully verified that InferencePool %s has no parent statuses.", poolNN.String())
+}
+
+// HTTPRouteMustBeAcceptedAndResolved waits for the specified HTTPRoute
+// to be Accepted and have its references resolved by the specified Gateway.
+// It uses the upstream Gateway API's HTTPRouteMustHaveCondition helper.
+func HTTPRouteMustBeAcceptedAndResolved(t *testing.T, c client.Client, timeoutConfig gatewayapiconfig.TimeoutConfig, routeNN, gatewayNN types.NamespacedName) {
+	t.Helper()
+
+	acceptedCondition := metav1.Condition{
+		Type:   string(gatewayv1.RouteConditionAccepted),
+		Status: metav1.ConditionTrue,
+		Reason: string(gatewayv1.RouteReasonAccepted),
+	}
+
+	resolvedRefsCondition := metav1.Condition{
+		Type:   string(gatewayv1.RouteConditionResolvedRefs),
+		Status: metav1.ConditionTrue,
+		Reason: string(gatewayv1.RouteReasonResolvedRefs),
+	}
+
+	t.Logf("Waiting for HTTPRoute %s to be Accepted by Gateway %s", routeNN.String(), gatewayNN.String())
+	gatewayk8sutils.HTTPRouteMustHaveCondition(t, c, timeoutConfig, routeNN, gatewayNN, acceptedCondition)
+
+	t.Logf("Waiting for HTTPRoute %s to have ResolvedRefs by Gateway %s", routeNN.String(), gatewayNN.String())
+	gatewayk8sutils.HTTPRouteMustHaveCondition(t, c, timeoutConfig, routeNN, gatewayNN, resolvedRefsCondition)
+
+	t.Logf("HTTPRoute %s is now Accepted and has ResolvedRefs by Gateway %s", routeNN.String(), gatewayNN.String())
+}
+
+// InferencePoolMustBeAcceptedByParent waits for the specified InferencePool
+// to report an Accepted condition with status True and reason "Accepted"
+// from at least one of its parent Gateways.
+func InferencePoolMustBeAcceptedByParent(t *testing.T, c client.Client, poolNN types.NamespacedName) {
+	t.Helper()
+
+	acceptedByParentCondition := metav1.Condition{
+		Type:   string(gatewayv1.GatewayConditionAccepted),
+		Status: metav1.ConditionTrue,
+		Reason: string(gatewayv1.GatewayReasonAccepted), // Expecting the standard "Accepted" reason
+	}
+
+	t.Logf("Waiting for InferencePool %s to be Accepted by a parent Gateway (Reason: %s)", poolNN.String(), gatewayv1.GatewayReasonAccepted)
+	InferencePoolMustHaveCondition(t, c, poolNN, acceptedByParentCondition)
+	t.Logf("InferencePool %s is Accepted by a parent Gateway (Reason: %s)", poolNN.String(), gatewayv1.GatewayReasonAccepted)
+}
diff --git a/docs/proposals/002-api-proposal/README.md b/docs/proposals/002-api-proposal/README.md
index f6d0c9e..2eb1111 100644
--- a/docs/proposals/002-api-proposal/README.md
+++ b/docs/proposals/002-api-proposal/README.md
@@ -122,13 +122,94 @@ type InferencePool struct {
         metav1.ObjectMeta
         metav1.TypeMeta
 
-        Spec InferencePoolSpec
+        Spec   InferencePoolSpec
+        Status InferencePoolStatus
 }
 
 type InferencePoolSpec struct {
-        // ModelServerSelector uses label selection to watch model server pods
+        // Selector defines a map of labels to watch model server pods
         // that should be included in the InferencePool.
-        ModelServerSelector map[string]string `json:"modelServerSelector,omitempty"`
+        // In some cases, implementations may translate this field to a Service selector, so this matches the simple
+        // map used for Service selectors instead of the full Kubernetes LabelSelector type.
+        // If sepecified, it will be applied to match the model server pods in the same namespace as the InferencePool.
+        // Cross namesoace selector is not supported.
+        Selector map[LabelKey]LabelValue `json:"selector"`
+
+        // TargetPortNumber defines the port number to access the selected model servers.
+        // The number must be in the range 1 to 65535.
+        TargetPortNumber int32 `json:"targetPortNumber"`
+
+        // EndpointPickerConfig specifies the configuration needed by the proxy to discover and connect to the endpoint
+        // picker service that picks endpoints for the requests routed to this pool.
+        EndpointPickerConfig `json:",inline"`
+}
+
+// EndpointPickerConfig specifies the configuration needed by the proxy to discover and connect to the endpoint picker extension.
+// This type is intended to be a union of mutually exclusive configuration options that we may add in the future.
+type EndpointPickerConfig struct {
+        // Extension configures an endpoint picker as an extension service.
+        ExtensionRef *Extension `json:"extensionRef,omitempty"`
+}
+
+// Extension specifies how to configure an extension that runs the endpoint picker.
+type Extension struct {
+      // Reference is a reference to a service extension.
+      ExtensionReference `json:",inline"`
+
+      // ExtensionConnection configures the connection between the gateway and the extension.
+      ExtensionConnection `json:",inline"`
+}
+
+// ExtensionReference is a reference to the extension deployment.
+type ExtensionReference struct {
+      // Group is the group of the referent.
+      // The default value is "", representing the Core API group.
+      Group *Group `json:"group,omitempty"`
+
+      // Kind is the Kubernetes resource kind of the referent. For example
+      // "Service".
+      //
+      // Defaults to "Service" when not specified.
+      //
+      // ExternalName services can refer to CNAME DNS records that may live
+      // outside of the cluster and as such are difficult to reason about in
+      // terms of conformance. They also may not be safe to forward to (see
+      // CVE-2021-25740 for more information). Implementations MUST NOT
+      // support ExternalName Services.
+      Kind *Kind `json:"kind,omitempty"`
+
+      // Name is the name of the referent.
+      Name ObjectName `json:"name"`
+
+      // The port number on the service running the extension. When unspecified,
+      // implementations SHOULD infer a default value of 9002 when the Kind is
+      // Service.
+      PortNumber *PortNumber `json:"portNumber,omitempty"`
+}
+
+// ExtensionConnection encapsulates options that configures the connection to the extension.
+type ExtensionConnection struct {
+      // Configures how the gateway handles the case when the extension is not responsive.
+      // Defaults to failClose.
+      FailureMode *ExtensionFailureMode `json:"failureMode"`
+}
+
+// ExtensionFailureMode defines the options for how the gateway handles the case when the extension is not
+type ExtensionFailureMode string
+
+
+// PoolStatus defines the observed state of InferencePool from a Gateway.
+type PoolStatus struct {
+      // GatewayRef indicates the gateway that observed state of InferencePool.
+      GatewayRef corev1.ObjectReference `json:"parentRef"`
+
+      // Conditions track the state of the InferencePool.
+      //
+      // Known condition types are:
+      //
+      // * "Accepted"
+      // * "ResolvedRefs"
+      Conditions []metav1.Condition `json:"conditions,omitempty"`
 }
 ```
 
@@ -147,6 +228,7 @@ type InferenceModel struct {
         metav1.TypeMeta
 
         Spec InferenceModelSpec
+        Status InferenceModelStatus
 }
 
 type InferenceModelSpec struct {
@@ -172,8 +254,21 @@ type InferenceModelSpec struct {
         // If not specified, the target model name is defaulted to the ModelName parameter.
         // ModelName is often in reference to a LoRA adapter.
         TargetModels []TargetModel
-        // Reference to the InferencePool that the model registers to. It must exist in the same namespace.
-        PoolReference *LocalObjectReference
+        // PoolRef is a reference to the inference pool, the pool must exist in the same namespace.
+        PoolRef PoolObjectReference
+}
+
+// PoolObjectReference identifies an API object within the namespace of the
+// referrer.
+type PoolObjectReference struct {
+        // Group is the group of the referent.
+        Group Group
+
+        // Kind is kind of the referent. For example "InferencePool".
+        Kind Kind
+
+        // Name is the name of the referent.
+        Name ObjectName
 }
 
 // Defines how important it is to serve the model compared to other models.
@@ -181,13 +276,17 @@ type InferenceModelSpec struct {
 // This allows us to union this with a oneOf field in the future should we wish to adjust/extend this behavior.
 type Criticality string
 const (
-    // Most important. Requests to this band will be shed last.
-    Critical  Criticality = "Critical"
-    // More important than Sheddable, less important than Critical.
-    // Requests in this band will be shed before critical traffic.
-    Default  Criticality = "Default"
-    // Least important. Requests to this band will be shed before all other bands.
-    Sheddable  Criticality = "Sheddable"
+        // Critical defines the highest level of criticality. Requests to this band will be shed last.
+        Critical Criticality = "Critical"
+
+        // Standard defines the base criticality level and is more important than Sheddable but less
+        // important than Critical. Requests in this band will be shed before critical traffic.
+        // Most models are expected to fall within this band.
+        Standard Criticality = "Standard"
+
+        // Sheddable defines the lowest level of criticality. Requests to this band will be shed before
+        // all other bands.
+        Sheddable Criticality = "Sheddable"
  )
 
 // TargetModel represents a deployed model or a LoRA adapter. The
@@ -200,24 +299,16 @@ const (
 type TargetModel struct {
         // The name of the adapter as expected by the ModelServer.
         Name string
-        // Weight is used to determine the percentage of traffic that should be 
+        // Weight is used to determine the percentage of traffic that should be
         // sent to this target model when multiple versions of the model are specified.
-        Weight *int
+        Weight *int32
 }
 
-// LocalObjectReference identifies an API object within the namespace of the
-// referrer.
-type LocalObjectReference struct {
-	// Group is the group of the referent. 
-	Group Group
-
-	// Kind is kind of the referent. For example "InferencePool".
-	Kind Kind
-
-	// Name is the name of the referent.
-	Name ObjectName
+// InferenceModelStatus defines the observed state of InferenceModel
+type InferenceModelStatus struct {
+	// Conditions track the state of the InferenceModel.
+	Conditions []metav1.Condition
 }
-
 ```
 
 ### Yaml Examples
@@ -225,27 +316,32 @@ type LocalObjectReference struct {
 #### InferencePool(s)
 Here we create a pool that selects the appropriate pods
 ```yaml
-apiVersion: inference.x-k8s.io/v1alpha1
+apiVersion: inference.x-k8s.io/v1alpha2
 kind: InferencePool
 metadata:
   name: base-model-pool
-  modelServerSelector:
-  - app: llm-server
+spec:
+  selector:
+    app: llm-server
+  targetNumber: 8080
+  extensionRef:
+    name: infra-backend-v1-app
 ```
 
 #### InferenceModel
 
 Here we consume the pool with two InferenceModels. Where `sql-code-assist` is both the name of the model and the name of the LoRA adapter on the model server. And `npc-bot` has a layer of indirection for those names, as well as a specified criticality. Both `sql-code-assist` and `npc-bot` have available LoRA adapters on the InferencePool and routing to each InferencePool happens earlier (at the K8s Gateway).
 ```yaml
-apiVersion: inference.x-k8s.io/v1alpha1
+apiVersion: inference.x-k8s.io/v1alpha2
 kind: InferenceModel
 metadata:
   name: sql-code-assist
 spec:
   modelName: sql-code-assist
-  poolRef: base-model-pool
+  poolRef:
+    name: base-model-pool
 ---
-apiVersion: inference.x-k8s.io/v1alpha1
+apiVersion: inference.x-k8s.io/v1alpha2
 kind: InferenceModel
 metadata:
   name: npc-bot
@@ -253,11 +349,12 @@ spec:
   modelName: npc-bot
   criticality: Critical
   targetModels:
-    targetModelName: npc-bot-v1
+    - name: npc-bot-v1
+      weight: 50
+    - name: npc-bot-v2
       weight: 50
-    targetModelName: npc-bot-v2
-      weight: 50 	
-  poolRef: base-model-pool
+  poolRef:
+    name: base-model-pool
 ```
 
 



Test patch:
diff --git a/conformance/tests/basic/httproute_invalid_inferencepool_ref.go b/conformance/tests/basic/httproute_invalid_inferencepool_ref.go
new file mode 100644
index 0000000..4893b81
--- /dev/null
+++ b/conformance/tests/basic/httproute_invalid_inferencepool_ref.go
@@ -0,0 +1,74 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+	http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// TODO(#864) refactor the structure to put all tests directly under tests instead of creating subfolders.
+package basic
+
+import (
+	"testing"
+
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/pkg/features"
+
+	"sigs.k8s.io/gateway-api-inference-extension/conformance/tests"
+)
+
+func init() {
+	tests.ConformanceTests = append(tests.ConformanceTests, HTTPRouteInvalidInferencePoolRef)
+}
+
+var HTTPRouteInvalidInferencePoolRef = suite.ConformanceTest{
+	ShortName:   "HTTPRouteInvalidInferencePoolRef",
+	Description: "Tests HTTPRoute status when it references an InferencePool that does not exist.",
+	Manifests:   []string{"tests/basic/httproute_invalid_inferencepool_ref.yaml"},
+	Features: []features.FeatureName{
+		features.FeatureName("SupportInferencePool"),
+		features.SupportGateway,
+	},
+	Test: func(t *testing.T, s *suite.ConformanceTestSuite) {
+		const (
+			appBackendNamespace = "gateway-conformance-app-backend"
+			infraNamespace      = "gateway-conformance-infra"
+			routeName           = "httproute-to-non-existent-pool"
+			gatewayName         = "conformance-gateway"
+		)
+		routeNN := types.NamespacedName{Name: routeName, Namespace: appBackendNamespace}
+		gatewayNN := types.NamespacedName{Name: gatewayName, Namespace: infraNamespace}
+
+		t.Run("HTTPRoute should have Accepted=True and ResolvedRefs=False for non-existent InferencePool", func(t *testing.T) {
+			acceptedCondition := metav1.Condition{
+				Type:   string(gatewayv1.RouteConditionAccepted),
+				Status: metav1.ConditionTrue,
+				Reason: string(gatewayv1.RouteReasonAccepted),
+			}
+			kubernetes.HTTPRouteMustHaveCondition(t, s.Client, s.TimeoutConfig, routeNN, gatewayNN, acceptedCondition)
+
+			resolvedRefsCondition := metav1.Condition{
+				Type:   string(gatewayv1.RouteConditionResolvedRefs),
+				Status: metav1.ConditionFalse,
+				Reason: string(gatewayv1.RouteReasonBackendNotFound),
+			}
+			kubernetes.HTTPRouteMustHaveCondition(t, s.Client, s.TimeoutConfig, routeNN, gatewayNN, resolvedRefsCondition)
+
+			t.Logf("Successfully verified HTTPRoute %s has conditions: Accepted=True and ResolvedRefs=False (Reason: BackendNotFound) for Gateway %s",
+				routeNN.String(), gatewayNN.String())
+		})
+	},
+}
diff --git a/conformance/tests/basic/httproute_invalid_inferencepool_ref.yaml b/conformance/tests/basic/httproute_invalid_inferencepool_ref.yaml
new file mode 100644
index 0000000..61bdb54
--- /dev/null
+++ b/conformance/tests/basic/httproute_invalid_inferencepool_ref.yaml
@@ -0,0 +1,31 @@
+# httproute_invalid_inferencepool_ref.yaml
+# This manifest defines an HTTPRoute that references an InferencePool
+# by name ("non-existent-inference-pool") which is intentionally NOT defined.
+# The test will verify that the HTTPRoute reflects an appropriate
+# failure status because the referenced InferencePool backend cannot be found.
+
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  # This name must match the 'routeNN.Name' in the Go test file.
+  name: httproute-to-non-existent-pool
+  # This namespace should be one created by the base manifests,
+  # typically where backend applications and their routes reside.
+  namespace: gateway-conformance-app-backend
+spec:
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: conformance-gateway # Name of the shared Gateway from base manifests
+    namespace: gateway-conformance-infra  # Namespace of the shared Gateway
+    sectionName: http
+  rules:
+  - backendRefs:
+    - group: inference.networking.x-k8s.io
+      kind: InferencePool
+      name: non-existent-inference-pool # Intentionally Non-Existing
+      port: 8080
+    matches:
+    - path:
+        type: PathPrefix
+        value: /test-non-existent-pool
diff --git a/conformance/tests/basic/inferencepool_accepted.go b/conformance/tests/basic/inferencepool_accepted.go
index 15eb6d7..d74f738 100644
--- a/conformance/tests/basic/inferencepool_accepted.go
+++ b/conformance/tests/basic/inferencepool_accepted.go
@@ -27,7 +27,7 @@ import (
 
 	// Import the tests package to append to ConformanceTests
 	"sigs.k8s.io/gateway-api-inference-extension/conformance/tests"
-	infrakubernetes "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
+	k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
 )
 
 func init() {
@@ -41,7 +41,10 @@ var InferencePoolAccepted = suite.ConformanceTest{
 	ShortName:   "InferencePoolAccepted",
 	Description: "A minimal InferencePool resource should be accepted by the controller and report an Accepted condition",
 	Manifests:   []string{"tests/basic/inferencepool_accepted.yaml"},
-	Features:    []features.FeatureName{},
+	Features: []features.FeatureName{
+		features.FeatureName("SupportInferencePool"),
+		features.SupportGateway,
+	},
 	Test: func(t *testing.T, s *suite.ConformanceTestSuite) {
 		// created by the associated manifest file.
 		poolNN := types.NamespacedName{Name: "inferencepool-basic-accepted", Namespace: "gateway-conformance-app-backend"}
@@ -54,7 +57,7 @@ var InferencePoolAccepted = suite.ConformanceTest{
 				Status: metav1.ConditionTrue,
 				Reason: "", // "" means we don't strictly check the Reason for this basic test.
 			}
-			infrakubernetes.InferencePoolMustHaveCondition(t, s.Client, poolNN, acceptedCondition)
+			k8sutils.InferencePoolMustHaveCondition(t, s.Client, poolNN, acceptedCondition)
 		})
 	},
 }
diff --git a/conformance/tests/basic/inferencepool_resolvedrefs_condition.go b/conformance/tests/basic/inferencepool_resolvedrefs_condition.go
new file mode 100644
index 0000000..86ca542
--- /dev/null
+++ b/conformance/tests/basic/inferencepool_resolvedrefs_condition.go
@@ -0,0 +1,104 @@
+/*
+Copyright 2025 The Kubernetes Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package basic
+
+import (
+	"context"
+	"testing"
+	"time"
+
+	"github.com/stretchr/testify/require"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/apimachinery/pkg/types"
+	gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
+	"sigs.k8s.io/gateway-api/conformance/utils/suite"
+	"sigs.k8s.io/gateway-api/pkg/features"
+
+	"sigs.k8s.io/gateway-api-inference-extension/conformance/tests"
+	k8sutils "sigs.k8s.io/gateway-api-inference-extension/conformance/utils/kubernetes"
+)
+
+func init() {
+	tests.ConformanceTests = append(tests.ConformanceTests, InferencePoolParentStatus)
+}
+
+var InferencePoolParentStatus = suite.ConformanceTest{
+	ShortName:   "InferencePoolResolvedRefsCondition",
+	Description: "Verify that an InferencePool correctly updates its parent-specific status (e.g., Accepted condition) when referenced by HTTPRoutes attached to shared Gateways, and clears parent statuses when no longer referenced.",
+	Manifests:   []string{"tests/basic/inferencepool_resolvedrefs_condition.yaml"},
+	Features: []features.FeatureName{
+		features.FeatureName("SupportInferencePool"),
+		features.SupportGateway,
+	},
+	Test: func(t *testing.T, s *suite.ConformanceTestSuite) {
+		const (
+			appBackendNamespace = "gateway-conformance-app-backend"
+			infraNamespace      = "gateway-conformance-infra"
+			poolName            = "multi-gateway-pool"
+			sharedGateway1Name  = "conformance-gateway"
+			sharedGateway2Name  = "conformance-secondary-gateway"
+			httpRoute1Name      = "httproute-for-gw1"
+			httpRoute2Name      = "httproute-for-gw2"
+		)
+
+		poolNN := types.NamespacedName{Name: poolName, Namespace: appBackendNamespace}
+		httpRoute1NN := types.NamespacedName{Name: httpRoute1Name, Namespace: appBackendNamespace}
+		httpRoute2NN := types.NamespacedName{Name: httpRoute2Name, Namespace: appBackendNamespace}
+		gateway1NN := types.NamespacedName{Name: sharedGateway1Name, Namespace: infraNamespace}
+		gateway2NN := types.NamespacedName{Name: sharedGateway2Name, Namespace: infraNamespace}
+
+		k8sutils.HTTPRouteMustBeAcceptedAndResolved(t, s.Client, s.TimeoutConfig, httpRoute1NN, gateway1NN)
+		k8sutils.HTTPRouteMustBeAcceptedAndResolved(t, s.Client, s.TimeoutConfig, httpRoute2NN, gateway2NN)
+
+		t.Run("InferencePool should show Accepted:True by parents when referenced by multiple HTTPRoutes", func(t *testing.T) {
+			k8sutils.InferencePoolMustBeAcceptedByParent(t, s.Client, poolNN)
+			// TODO(#865) ensure requests are correctly routed to this InferencePool.
+			t.Logf("InferencePool %s has parent status Accepted:True as expected with two references.", poolNN.String())
+		})
+
+		t.Run("Delete httproute-for-gw1", func(t *testing.T) {
+			httproute1 := &gatewayv1.HTTPRoute{
+				ObjectMeta: metav1.ObjectMeta{Name: httpRoute1NN.Name, Namespace: httpRoute1NN.Namespace},
+			}
+			t.Logf("Deleting HTTPRoute %s", httpRoute1NN.String())
+			require.NoError(t, s.Client.Delete(context.TODO(), httproute1), "failed to delete httproute-for-gw1")
+			time.Sleep(s.TimeoutConfig.GatewayMustHaveCondition)
+		})
+
+		t.Run("InferencePool should still show Accepted:True by parent after one HTTPRoute is deleted", func(t *testing.T) {
+			k8sutils.InferencePoolMustBeAcceptedByParent(t, s.Client, poolNN)
+			// TODO(#865) ensure requests are correctly routed to this InferencePool.
+			t.Logf("InferencePool %s still has parent status Accepted:True as expected with one reference remaining.", poolNN.String())
+		})
+
+		t.Run("Delete httproute-for-gw2", func(t *testing.T) {
+			httproute2 := &gatewayv1.HTTPRoute{
+				ObjectMeta: metav1.ObjectMeta{Name: httpRoute2NN.Name, Namespace: httpRoute2NN.Namespace},
+			}
+			t.Logf("Deleting HTTPRoute %s", httpRoute2NN.String())
+			require.NoError(t, s.Client.Delete(context.TODO(), httproute2), "failed to delete httproute-for-gw2")
+		})
+
+		t.Run("InferencePool should have no parent statuses after all HTTPRoutes are deleted", func(t *testing.T) {
+			t.Logf("Waiting for InferencePool %s to have no parent statuses.", poolNN.String())
+			k8sutils.InferencePoolMustHaveNoParents(t, s.Client, poolNN)
+			t.Logf("InferencePool %s correctly shows no parent statuses, indicating it's no longer referenced.", poolNN.String())
+		})
+
+		t.Logf("InferencePoolResolvedRefsCondition completed.")
+	},
+}
diff --git a/conformance/tests/basic/inferencepool_resolvedrefs_condition.yaml b/conformance/tests/basic/inferencepool_resolvedrefs_condition.yaml
new file mode 100644
index 0000000..0088931
--- /dev/null
+++ b/conformance/tests/basic/inferencepool_resolvedrefs_condition.yaml
@@ -0,0 +1,131 @@
+# conformance/tests/basic/inferencepool_resolvedrefs_condition.yaml
+
+# This manifest defines the initial resources for the
+# inferencepool_resolvedrefs_condition.go conformance test.
+
+# --- Backend Deployment (using agnhost echo server) ---
+# This Deployment provides Pods for the InferencePool to select.
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: infra-backend-deployment
+  namespace: gateway-conformance-app-backend
+  labels:
+    app: infra-backend
+spec:
+  replicas: 1
+  selector:
+    matchLabels:
+      app: infra-backend
+  template:
+    metadata:
+      labels:
+        app: infra-backend
+    spec:
+      containers:
+      - name: agnhost-echo
+        image: k8s.gcr.io/e2e-test-images/agnhost:2.39
+        args:
+        - serve-hostname
+        - --port=8080
+        ports:
+        - name: http
+          containerPort: 8080
+        readinessProbe:
+          httpGet:
+            path: /
+            port: 8080
+          initialDelaySeconds: 3
+          periodSeconds: 5
+          failureThreshold: 2
+
+---
+# --- Backend Service ---
+# Service for the infra-backend-deployment.
+apiVersion: v1
+kind: Service
+metadata:
+  name: infra-backend-svc
+  namespace: gateway-conformance-app-backend
+spec:
+  selector:
+    app: infra-backend
+  ports:
+  - name: http
+    protocol: TCP
+    port: 8080
+    targetPort: 8080
+  - name: epp
+    port: 9002
+    targetPort: 9002
+
+---
+# --- InferencePool Definition ---
+apiVersion: inference.networking.x-k8s.io/v1alpha2
+kind: InferencePool
+metadata:
+  name: multi-gateway-pool # Name used in the Go test
+  namespace: gateway-conformance-app-backend # Defined in base manifests.yaml
+spec:
+  # --- Selector (Required) ---
+  # Selects the Pods belonging to this pool.
+  selector:
+    app: "infra-backend"
+  # --- Target Port (Required) ---
+  targetPortNumber: 8080
+  extensionRef:
+    name: infra-backend-svc
+
+---
+# --- HTTPRoute for Gateway 1 (conformance-gateway) ---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: httproute-for-gw1
+  namespace: gateway-conformance-app-backend
+spec:
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: conformance-gateway
+    namespace: gateway-conformance-infra
+    sectionName: http
+  hostnames:
+  - "gw1.example.com"
+  rules:
+  - backendRefs:
+    - group: inference.networking.x-k8s.io
+      kind: InferencePool
+      name: multi-gateway-pool
+      port: 8080
+    matches:
+    - path:
+        type: PathPrefix
+        value: /conformance-gateway-test
+
+---
+# --- HTTPRoute for Gateway 2 (conformance-secondary-gateway) ---
+apiVersion: gateway.networking.k8s.io/v1
+kind: HTTPRoute
+metadata:
+  name: httproute-for-gw2
+  namespace: gateway-conformance-app-backend
+spec:
+  parentRefs:
+  - group: gateway.networking.k8s.io
+    kind: Gateway
+    name: conformance-secondary-gateway
+    namespace: gateway-conformance-infra
+    sectionName: http
+  hostnames:
+  - "secondary.example.com"
+  rules:
+  - backendRefs:
+    - group: inference.networking.x-k8s.io
+      kind: InferencePool
+      name: multi-gateway-pool
+      port: 8080
+    matches:
+    - path:
+        type: PathPrefix
+        value: /gateway-2-test