# How the Routing Engine in reverse-skill Scores and Prioritizes Tasks

> Discover how the reverse-skill routing engine scores and prioritizes tasks. Learn about its three-stage pipeline for deterministic skill assignment.

- Repository: [ZhaoXu/reverse-skill](https://github.com/zhaoxuya520/reverse-skill)
- Tags: internals
- Published: 2026-08-30

---

**The routing engine in reverse-skill uses a three-stage pipeline—keyword matching, cumulative scoring, and priority-ordered selection—to transform a free-form task hint into a deterministic PRIMARY skill assignment.**

The reverse-skill repository implements a data-driven routing system that maps natural language task descriptions to specialized reverse-engineering workflows. At its core, the system relies on `skills/scripts/master-route.ps1` and the configuration file [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) to evaluate user input and select the most appropriate skill module. Understanding how this routing engine scores and prioritizes tasks is essential for customizing the framework or debugging route selection behavior.

## Stage 1: Keyword Matching Against Task Hints

In `skills/scripts/master-route.ps1`, the engine normalizes the user-supplied hint by lower-casing it into the variable `$t`. It then evaluates each route defined in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), checking whether any **keyword** objects contained in that route hit the normalized hint【master-route.ps1 L35-L51】.

The matching logic respects three constraint fields:

- **`must`** – The hint must contain this specific substring
- **`mustAll`** – Every specified substring in the list must be present
- **`exclude`** – If this substring appears, the route is immediately disqualified

When a keyword object successfully hits, the corresponding route ID is added to the candidate set `$sel` for further processing.

## Stage 2: Cumulative Scoring Calculation

Every time a route appears in the candidate set, the engine increments its score using a hashtable operation:

```powershell
$scores[$item] = $scores[$item] + 1

```

This cumulative approach means a route matching multiple independent keyword objects receives a higher score than one matching only a single constraint【master-route.ps1 L55-L59】. The scoring system inherently rewards specificity—routes with broader keyword coverage naturally accumulate more points and outrank generic competitors.

## Stage 3: Priority-Based Selection

After calculating all scores, the engine consults the ordered `priority` array defined in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json)【routing.json L24-L29】. It iterates through this list sequentially and selects the first route ID that possesses a non-zero score.

This **priority-ordered selection** mechanism ensures deterministic tie-breaking. Even if multiple routes achieve identical high scores, the one appearing earliest in the configured priority list wins the PRIMARY designation【master-route.ps1 L74-L87】.

## Confidence Levels and Fallback Handling

The engine calculates a confidence level immediately after selecting the primary route【master-route.ps1 L96-L98】:

- **High** – Exactly one unique route matched (`$uniq.Count -eq 1`)
- **Medium** – Multiple routes matched, but priority ordering resolved to a single primary
- **Low** – No routes matched; the system defaulted to the configured `fallbackId`

If no candidate obtains a score, the engine detects the empty set condition and falls back to the `fallbackId` defined in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) (typically `R0`, representing "General reverse-engineering")【routing.json L5-L7】. Similarly, if the selected primary ID is missing from the routes table due to a configuration typo, the engine logs a warning and safely falls back to the `fallbackId` rather than crashing【master-route.ps1 L99-L103】.

## Configuration Validation and Guardrails

The routing engine includes defensive programming to ensure configuration integrity. During initialization, `master-route.ps1` verifies that every route ID listed in the `priority` array actually exists in the `routes` table, emitting warnings for any mismatches【master-route.ps1 L64-L72】.

For continuous integration validation, the repository provides `skills/scripts/verify-routing-coherence.ps1`. This helper script validates the one-to-one correspondence between [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) and the priority table documented in [`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md), ensuring that the JSON schema remains the single source of truth.

## Running the Router

You can invoke the routing engine directly to test how it scores specific task hints.

On Windows:

```powershell
powershell -File skills/scripts/master-route.ps1 -Hint "apk reverse static analysis"

```

On Linux, macOS, or Kali:

```bash
bash skills/scripts/master-route.sh --hint "analyse a malicious email campaign"

```

After execution, inspect the generated [`route-scope.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/route-scope.md) file to view the PRIMARY selection and confidence rating:

```powershell
type $(ls work/master-route-*/route-scope.md)

```

*Example output:*

```

PRIMARY -> skills/apk-reverse/SKILL.md
Label: APK reverse | confidence: high
Wrote /path/to/work/master-route-20241012-154212/route-scope.md
ACTION: Open PRIMARY SKILL.md now and execute ACTION REQUIRED.

```

In this example, the hint "apk reverse static analysis" matches the `must` pattern for route **R1** (APK reverse), giving it a score of 1. With no competing matches, the engine designates **R1** as PRIMARY with *high* confidence.

## Summary

- The **routing engine** processes hints through three deterministic stages: keyword matching, cumulative scoring, and priority-ordered selection.
- Routes are defined in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), while execution logic resides in `skills/scripts/master-route.ps1`.
- **Cumulative scoring** rewards routes that match multiple keyword constraints, while the **priority array** breaks ties based on configuration order.
- **Confidence levels** (high, medium, low) reflect the uniqueness of the match result and whether a fallback was used.
- Robust **guardrails** validate route IDs against the priority list and automatically default to `fallbackId` (`R0`) when no matches occur or when configuration errors are detected.

## Frequently Asked Questions

### How does the routing engine handle hints that match multiple routes?

When multiple routes match, the engine increments scores for all candidates. It then traverses the ordered `priority` array and selects the first route ID that has a non-zero score. If multiple routes share the top score but appear at different positions in the priority list, the one listed earlier wins. This scenario typically yields a **medium** confidence rating because alternative matches existed but were deprioritized.

### What happens if no routes match the provided hint?

If no keyword constraints hit the input hint, all routes retain a score of zero. The engine detects this condition and falls back to the `fallbackId` specified in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) (typically `R0`, the "General reverse-engineering" skill)【routing.json L5-L7】. This results in a **low** confidence designation since the system defaulted rather than selected a specific match.

### Can a route be excluded based on negative keywords?

Yes. The routing logic supports an **`exclude`** field within keyword objects. If the user's hint contains text matching an exclusion pattern, that route is immediately disqualified from the candidate set, regardless of whether it also matches positive criteria like `must` or `mustAll`.

### Where is the routing configuration stored and how is it validated?

The single source of truth is [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), which defines all routes, their keyword rules, the fallback ID, and the global priority order. The script `skills/scripts/verify-routing-coherence.ps1` provides CI validation to ensure every route ID in the priority list corresponds to a valid entry in the routes table. Additionally, `master-route.ps1` performs runtime validation of route IDs against the priority list to prevent execution errors.