# How Routing Rules Are Scored and Prioritized in reverse-skill: A Complete Guide

> Learn how reverse-skill scores and prioritizes routing rules. Understand weighted keyword matching, priority arrays, and fallback rules for efficient skill selection.

- Repository: [ZhaoXu/reverse-skill](https://github.com/zhaoxuya520/reverse-skill)
- Tags: how-to-guide
- Published: 2026-08-21

---

**reverse-skill selects the appropriate skill by calculating a weighted keyword match score for each rule defined in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), using the ordered `priority` array to break ties, and defaulting to the fallback rule `R0` when no keywords match.**

The open-source **reverse-skill** project automates skill selection through a deterministic routing system that evaluates user hints against configured rules. Understanding how this mechanism calculates match scores and resolves conflicts is essential for customizing the framework. This guide examines the scoring algorithm, priority resolution, and fallback behavior implemented in `scripts/master-route.ps1` and [`scripts/master-route.sh`](https://github.com/zhaoxuya520/reverse-skill/blob/main/scripts/master-route.sh).

## Routing Configuration and Rule Structure

All routing logic is governed by [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), which serves as the single source of truth for the entire system.

### The routing.json Schema

The JSON file contains two top-level keys: `routes` and `priority`. The `routes` object maps rule IDs (e.g., `R1`, `R50`) to configuration objects containing `title`, `keywords`, and `skillPath`. The `priority` array defines a global ordering of rule IDs from most preferred to least preferred.

```json
{
  "routes": {
    "R50": {
      "title": "Web-app pentest",
      "keywords": {
        "web": 2,
        "sql": 3,
        "xss": 2,
        "csrf": 1
      },
      "skillPath": "skills/pentest-tools/web-app"
    }
  },
  "priority": ["R1", "R2", "R40", "R50", "R0"]
}

```

### Keyword Weights and Default Values

Each keyword within a rule’s `keywords` object carries an integer weight. When the router tokenizes a user hint, **unweighted keywords default to a score contribution of 1**. The final score for a rule equals the sum of weights for all keywords present in the user input.

## The Scoring Algorithm Step-by-Step

The platform-specific router scripts implement identical logic to ensure consistent behavior across Windows and Unix environments.

### Input Tokenization

The router first normalizes the user hint by converting it to lowercase and splitting it into individual tokens based on whitespace. This ensures case-insensitive matching against the keyword definitions in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json).

```powershell
$hint = "SQL injection and XSS in a web portal"
$tokens = $hint.ToLower().Split(' ', [StringSplitOptions]::RemoveEmptyEntries)

```

### Score Calculation Logic

For each rule ID in the `routes` object, the router initializes a score of zero. It then iterates through the rule’s keyword dictionary, adding the associated weight to the score whenever a keyword exists within the token array.

```powershell
$bestRule = $null
$bestScore = -1

foreach ($id in $routing.routes.Keys) {
    $score = 0
    foreach ($kw in $routing.routes[$id].keywords.GetEnumerator()) {
        if ($tokens -contains $kw.Key) {
            $score += $kw.Value
        }
    }
    # Selection logic continues...

}

```

### Priority-Based Tie Breaking

When multiple rules achieve identical high scores, the router consults the `priority` array to determine precedence. The rule whose ID appears earlier in the array wins the tie-break, as the array is ordered from highest to lowest preference.

```powershell
elseif ($score -eq $bestScore) {
    $posBest = $routing.priority.IndexOf($bestRule)
    $posCurr = $routing.priority.IndexOf($id)
    if ($posCurr -lt $posBest) {
        $bestRule = $id
    }
}

```

## Cross-Platform Router Implementations

The scoring and prioritization logic is duplicated across platform-specific entry points to ensure deterministic routing regardless of the host operating system.

### Windows Implementation (master-route.ps1)

`scripts/master-route.ps1` handles the entire workflow for Windows environments, including JSON parsing, tokenization, and score evaluation. According to [`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md), this script maintains strict adherence to the priority list defined in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json).

### Linux and macOS Implementation (master-route.sh)

[`scripts/master-route.sh`](https://github.com/zhaoxuya520/reverse-skill/blob/main/scripts/master-route.sh) provides equivalent functionality for Linux, macOS, and Kali systems. Both scripts reference the same configuration file, guaranteeing that rule modifications in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) propagate immediately across all supported platforms without code changes.

## Fallback Behavior and Disambiguation

If no rule accumulates a score greater than zero—indicating zero keyword matches—the router selects the **fallback rule `R0`**. When this occurs, the system typically prompts the operator to consult [`skills/routing.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/routing.md), which contains a human-readable matrix for manual disambiguation. This fail-safe ensures that unrecognized hints do not silently fail but instead direct the user toward the appropriate skill documentation.

## Summary

- **Configuration Location**: All routing rules, keyword weights, and the priority array reside in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json).
- **Scoring Mechanism**: Scores are calculated as the sum of matched keyword weights, with unweighted keywords contributing `1`.
- **Tie Resolution**: Identical scores are resolved by the order of rule IDs in the `priority` array (earlier IDs win).
- **Platform Consistency**: `scripts/master-route.ps1` and [`scripts/master-route.sh`](https://github.com/zhaoxuya520/reverse-skill/blob/main/scripts/master-route.sh) implement identical algorithms for cross-platform parity.
- **Fallback Path**: Rule `R0` serves as the default when no keywords match, directing users to [`skills/routing.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/routing.md) for clarification.

## Frequently Asked Questions

### How does reverse-skill calculate routing scores?

The router tokenizes the input hint into lowercase words and sums the weights of all matching keywords found in each rule’s configuration within [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json). Keywords without explicit weights contribute a value of `1` to the total.

### What happens when two routing rules have the same score?

When multiple rules achieve identical high scores, the router references the `priority` array in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json). The rule whose ID appears closest to the beginning of this ordered list is selected, allowing administrators to define strict precedence hierarchies independent of keyword weights.

### Where is the routing priority list defined?

The priority list is defined as a JSON array named `priority` in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json). This array contains rule ID strings ordered from most preferred to least preferred, and it is consulted exclusively for tie-breaking when scores are equal.

### What occurs if no routing rules match the input hint?

If no keywords match the input, all rules receive a score of zero. The router then selects the fallback rule `R0` and typically alerts the operator to review [`skills/routing.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/routing.md) for manual disambiguation, ensuring the system fails gracefully rather than executing an incorrect skill.