---
name: routing-data-plane-e2e
description: Build or verify end-to-end control-plane plus data-plane flows for logical-group routing systems. Use this whenever the task involves logical groups, routes, shadow groups, shadow hosts, shadow models, managed keys, chat proxy bridges, sticky routing, failover, cooldowns, route health, or proving that a routed request really hit the intended upstream account. Also use it for Chinese requests such as “逻辑分组”, “智能路由”, “shadow_group”, “managed key”, “真实 chat/completions 验证”, or “从控制面到数据面闭环”.
---

# Routing Data Plane E2E

This skill is for systems where configuration and request execution are split across layers.

Typical shape:

- control plane: logical groups, routes, public models, bindings
- runtime plane: sticky state, cooldowns, failover counters
- data plane: actual `/v1/chat/completions` or similar request path

The job is not finished until all three layers line up.

## Core model

Use this mental model:

- `logical_group` = product-facing grouping
- `route` = routing choice inside that grouping
- `shadow_group` = real host-side target group
- `shadow_model` = real host-side model name

Keep aliases and public naming in the plugin layer whenever possible.

## Canonical shadow rule

Do not push public alias complexity down into the stock host unless you have verified the host supports it cleanly.

Preferred approach:

- plugin exposes public model naming
- shadow provider uses canonical upstream model naming
- host only sees the canonical shadow model

Use this especially if alias-in-shadow previously caused pricing restriction or availability bugs.

## Acceptance chain

### 1. Control plane

- create or load the `logical_group`
- create or load the `route`
- bind public model to route
- confirm shadow host, shadow group, and shadow model are present

### 2. Runtime plane

- verify sticky backend
- verify route health or route state
- if applicable, verify cooldown and failure counters

### 3. Resolve step

- call the resolver
- capture selected `route_id`
- capture selected `shadow_host_id`
- capture selected `shadow_group_id`
- capture selected `shadow_model`

### 4. Data plane

- send a real routed request through the formal routing endpoint
- verify upstream status code
- verify the selected route in decision logs

### 5. Host-side proof

- verify host-side usage evidence
- confirm the request hit the intended group, account, and model

If step 5 is missing, you have a plausible path, not a proved path.

## Preferred proof sources

Use these together:

- route decision logs
- sticky audit logs
- failover event logs
- host `usage_logs`
- host account or group metadata

Do not rely only on:

- front-end page state
- route list APIs
- `api_keys.usage_*` counters if host `usage_logs` are available

## Sticky and failover expectations

For stable verification:

- first request should usually bind sticky
- second identical request should usually hit sticky
- cooldown or failure threshold should cause fallback
- fallback should produce a failover event
- repeated request after fallback should stabilize on the new route

If these do not line up, the route layer is not yet production-ready.

## Host limitations to watch

- one host group may not support multiple channels cleanly
- alias-based model restriction can cause apparent availability with actual request failure
- route binding ambiguity can pollute provider account ownership

If the host resists the desired abstraction, move complexity back into the plugin layer rather than forcing the host model.

## Final E2E checklist

Before calling a routing task complete, confirm:

- logical group exists
- route exists
- public model binding exists
- provider account is imported and bound
- effective gateway key source is known
- routed request returns the expected upstream status
- host usage evidence matches the intended route, account, and model
- temporary test entities are cleaned if they would pollute later work
