# How the target_selector Policy Routes Requests Among Multiple Targets in Switchyard

> Learn how the target_selector policy in Switchyard routes requests by mapping classifier verdicts to runtime models for deterministic classification. Understand its abstention mechanism.

- Repository: [NVIDIA-NeMo/Switchyard](https://github.com/NVIDIA-NeMo/Switchyard)
- Tags: how-to-guide
- Published: 2026-09-12

---

**The target_selector policy uses a configurable JSON Pointer to extract a category from a classifier's verdict, maps that category to a runtime model via the Driver, and returns a deterministic classification with confidence 1.0, or abstains by returning an empty ambiguous classification if the target is missing or invalid.**

The target_selector policy in NVIDIA Switchyard provides deterministic request routing by interpreting structured output from upstream classifiers. Implemented in the `libsy` crate, this policy bridges the gap between classifier verdicts and concrete model selection, enabling declarative routing based on JSON payload content.

## Policy Definition and JSON Pointer Configuration

The policy is implemented in [`crates/libsy/src/algorithms/util/target_selector.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/libsy/src/algorithms/util/target_selector.rs) within the `TargetSelectorPolicy` struct. During initialization, the `new` method parses and validates a **JSON Pointer** (stored as `selector`) that points to a specific field inside the classifier's validated verdict JSON payload.

```rust
use switchyard_libsy::algorithms::util::target_selector::TargetSelectorPolicy;

// Configure the policy to look for the target in the "decision/target" field
let policy = TargetSelectorPolicy::new("/decision/target")?;

```

The pointer must resolve to a string value representing a valid model category. The parsing and validation logic ensures the pointer syntax is correct before the policy enters the routing chain.

## Resolving Verdicts to Categories

When processing a request, the `to_classification` method resolves the configured pointer against the incoming JSON verdict payload. The method extracts the string value at the pointer location and attempts to parse it into a `Category` enum variant (e.g., `capable`, `efficient`). 

If the extracted value resolves to `Judge`, the policy explicitly ignores it because judges do not correspond to routing targets in the Switchyard architecture. According to the source code in [`target_selector.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/target_selector.rs) (lines 44-50), this special case prevents judicial verdicts from being mistakenly routed as computational targets.

## Mapping Categories to Runtime Models

After identifying a valid category, the policy queries the **Driver** for available runtime models via `driver.models_for(&category)`. The implementation selects the first model returned in this list as the target. It then constructs a `Classification::Scores` entry with a fixed **confidence score of 1.0**, attaching the chosen category to the result.

```rust
// The driver provides models organized by category
let models = driver.models_for(&category);
// First model becomes the deterministic target
let target_model = models.first().ok_or_else(|| Error::NoModelsAvailable)?;

```

This approach guarantees deterministic routing behavior—when the JSON pointer resolves successfully and the category exists, the policy always selects the first available model for that category with absolute confidence.

## Handling Missing or Invalid Targets

The target_selector policy implements graceful degradation through explicit abstention. If any of the following conditions occur, the policy returns `Classification::Ambiguous(vec![])`:

- The JSON pointer cannot be resolved against the verdict payload
- The extracted value is not a known category variant
- The category has no available runtime models registered with the Driver

As implemented in [`target_selector.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/target_selector.rs) (lines 60-62), this empty ambiguous classification signals to the Switchyard routing algorithm that the policy abstains from making a selection. The request then falls back to the next policy in the chain, allowing for sophisticated fallback routing strategies.

## Integration with the Switchyard Algorithm

The policy integrates into the main routing pipeline through the `CustomClassifierPolicy` enum variant. In [`crates/switchyard-runner/src/algorithm.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/switchyard-runner/src/algorithm.rs) (lines 87-89), the runner constructs the `TargetSelector` variant from the configuration selector string and invokes it during the classification phase.

```rust
// From algorithm.rs - constructing the policy from config
let target_policy = CustomClassifierPolicy::TargetSelector(
    TargetSelectorPolicy::new(&config.selector)?
);

```

The resulting `Classification` drives the final model-selection step, determining which downstream model processes the request.

## Practical Examples

### Basic Routing Scenario

The following example demonstrates routing a request to the "capable" category based on a classifier verdict:

```rust
use switchyard_libsy::algorithms::util::target_selector::TargetSelectorPolicy;
use switchyard_libsy::core::algorithm::Driver;
use switchyard_libsy::core::category::Category;
use switchyard_libsy::core::model::ModelId;
use serde_json::json;
use std::sync::Arc;

// Initialize driver with models for specific categories
let driver = Driver::new(
    "example",
    Arc::new(RuntimeModels::new(
        [
            (Category::Capable, vec![ModelId::from("model/opus")]),
            (Category::Efficient, vec![ModelId::from("model/fast")]),
        ]
        .into(),
    )),
)
.0;

// Configure policy to extract target from nested JSON field
let policy = TargetSelectorPolicy::new("/decision/target")?;

// Simulate classifier output specifying the "capable" category
let verdict = json!({
    "decision": { "target": "capable" }
});

// Convert verdict to routing classification
let classification = policy.to_classification(Some(&verdict), &driver)?;

// Extract selected model
let selected_model = classification.argmax(false)?.map(|score| score.target);
assert_eq!(selected_model, Some(ModelId::from("model/opus")));

```

### Abstention on Unknown Categories

When the verdict contains an unrecognized target, the policy abstains:

```rust
let policy = TargetSelectorPolicy::new("/target")?;
let verdict = json!({ "target": "unknown_category" });
let classification = policy.to_classification(Some(&verdict), &driver)?;

// Returns None, indicating abstention from routing
assert!(classification.argmax(false)?.is_none());

```

## Summary

- The **target_selector policy** resides in [`crates/libsy/src/algorithms/util/target_selector.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/libsy/src/algorithms/util/target_selector.rs) and provides deterministic routing based on JSON Pointer extraction.
- It parses classifier verdicts using a configurable **JSON Pointer** to identify target categories, ignoring the `Judge` category specifically.
- Valid targets map to the first available runtime model for that category via `driver.models_for(&category)`, returning a **confidence score of 1.0**.
- When pointers fail to resolve, categories are unknown, or no models exist, the policy returns `Classification::Ambiguous(vec![])` to **abstain** and trigger fallback routing.
- The policy integrates into the Switchyard runner as a `CustomClassifierPolicy::TargetSelector` variant, constructed in [`switchyard-runner/src/algorithm.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/switchyard-runner/src/algorithm.rs).

## Frequently Asked Questions

### What happens when the target_selector policy cannot resolve the JSON pointer?

When the configured JSON Pointer fails to resolve against the verdict payload, or when the resolved value is not a valid `Category` variant, the policy returns `Classification::Ambiguous(vec![])`. This empty ambiguous result signals the Switchyard routing algorithm to abstain from selection and proceed to the next policy in the chain.

### How does target_selector handle the Judge category?

The policy explicitly excludes the `Judge` category from routing consideration. In `to_classification`, if the extracted string resolves to `Category::Judge`, the implementation treats this as an invalid routing target and proceeds to return an ambiguous classification, ensuring judicial verdicts do not route to computational models.

### Is the target_selector policy deterministic?

Yes, the target_selector policy provides fully deterministic routing. When a valid category is extracted and models exist for that category, the policy always selects the first model from `driver.models_for(&category)` and assigns it a confidence score of exactly 1.0. This ensures consistent, reproducible routing decisions for identical inputs.

### Where is the target_selector policy configured in Switchyard?

Configuration occurs in the Switchyard runner algorithm at [`crates/switchyard-runner/src/algorithm.rs`](https://github.com/NVIDIA-NeMo/Switchyard/blob/main/crates/switchyard-runner/src/algorithm.rs) (lines 87-89). The runner constructs the policy from a configuration string specifying the JSON Pointer path, wrapping it as a `CustomClassifierPolicy::TargetSelector` variant before incorporating it into the classification pipeline.