# How Reverse‑Skill's Priority‑Based Routing System Works in routing.json

> Understand Reverse-Skill's priority-based routing system and its three-stage matching algorithm in routing.json for efficient skill selection. Learn how it works.

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

---

**Reverse‑Skill uses a three‑stage matching algorithm in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) to select the most relevant skill: keyword matching, highest‑score selection, and priority‑list tie‑breaking.**

The [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) file serves as the single source of truth for determining which markdown skill file to invoke for a given reverse‑engineering or pentesting request. This article explains the priority‑based routing system by examining the actual JSON structure and the PowerShell scripts that execute the logic.

---

## Routing.json Structure Overview

The configuration file contains four top‑level sections that control skill selection:

- **`meta`** — Contains the `fallbackId` (default `R0`) and a human‑readable description of the scoring algorithm
- **`routes`** — Defines `R1` through `R41`, each with keyword rules and a target `skill` file path
- **`priority`** — Ordered array that resolves ties when multiple routes achieve the same score
- **`defaultSkill`** — Fallback skill used when routing fails entirely

The `meta.scoring` field (line 6) explicitly documents the algorithm: candidates enter the pool when any keyword rule matches, the highest score wins, and the priority list breaks ties with earlier entries preferred.

---

## Stage 1: Keyword Matching with Regex Rules

Each route contains a `keywords` array of rule objects. Every rule supports three matching conditions:

| Field | Purpose | Required |
|-------|---------|----------|
| `must` | Regex that **must** match the request | Yes |
| `exclude` | Regex that **must not** match (filters false positives) | No |
| `mustAll` | Array of regexes where **all** must match | No |

A route receives a *hit* when **any** of its rules evaluates to true. The route's score equals its total number of matching rules across all keyword entries.

Consider route `R1` for APK reverse engineering:

```json
"R1": {
  "keywords": [
    {
      "must": "\\bandroid\\b",
      "exclude": "\\bios\\b",
      "mustAll": ["\\bapk\\b", "\\breverse\\b"]
    },
    {
      "must": "\\bsmali\\b"
    }
  ],
  "skill": "apk-reverse/SKILL.md"
}

```

The first rule requires "android" without "ios", plus both "apk" and "reverse". The second rule matches "smali" alone. If both rules match, `R1` scores 2.

---

## Stage 2: Candidate Scoring and Selection

After evaluating all routes, the engine builds a candidate set containing only routes with score > 0. The algorithm then:

1. Finds the **maximum score** across all candidates
2. Filters to routes achieving that maximum
3. Uses the **`priority` array** to select the first matching route

This prioritization mechanism ensures deterministic behavior when multiple routes are equally specific.

The priority array (truncated) appears as:

```json
"priority": [
  "R4",
  "R1",
  "R2",
  "R3",
  "R5",
  "R6",
  "R7",
  "R8",
  "R9",
  "R10",
  "R11",
  "R12",
  "R13",
  "R14",
  "R15",
  "R16",
  "R17",
  "R18",
  "R19",
  "R20",
  "R21",
  "R22",
  "R23",
  "R24",
  "R25",
  "R26",
  "R27",
  "R28",
  "R29",
  "R30",
  "R31",
  "R32",
  "R33",
  "R34",
  "R35",
  "R36",
  "R37",
  "R38",
  "R39",
  "R40",
  "R41",
  "R0"
]

```

If `R1` and `R4` both score 2, `R4` wins because it appears earlier in the priority list.

---

## Stage 3: Fallback Handling

When **no** keyword rules match, the engine routes to `meta.fallbackId` (`R0` by convention). Route `R0` typically contains a generic skill or a request‑for‑clarification prompt.

The fallback ensures the system degrades gracefully rather than failing silently on ambiguous inputs.

---

## Script Implementation in master-route.ps1

The routing logic executes in `skills/scripts/master-route.ps1` (with a POSIX counterpart in [`master-route.sh`](https://github.com/zhaoxuya520/reverse-skill/blob/main/master-route.sh)). The script implements the algorithm as follows:

```powershell

# Load routing configuration

$routing = Get-Content -Raw -Path "$PSScriptRoot/../config/routing.json" | ConvertFrom-Json

# Receive user hint via --hint parameter

$hint = $args | Select-String '^--hint=(.+)$' | ForEach-Object { $_.Matches.Groups[1].Value }

# Stage 1: Score all routes

$candidates = @()
foreach ($routeId in $routing.routes.Keys) {
    $score = 0
    $route = $routing.routes.$routeId
    
    foreach ($rule in $route.keywords) {
        $matchesMust = $hint -cmatch $rule.must
        $notExcluded = !($rule.exclude) -or ($hint -cnotmatch $rule.exclude)
        $allMustMatch = !($rule.mustAll) -or ($rule.mustAll | ForEach-Object { $hint -cmatch $_ } | Where-Object { $_ } | Measure-Object).Count -eq $rule.mustAll.Count
        
        if ($matchesMust -and $notExcluded -and $allMustMatch) {
            $score++
        }
    }
    
    if ($score -gt 0) {
        $candidates += [pscustomobject]@{
            Id = $routeId
            Score = $score
            Skill = $route.skill
        }
    }
}

# Stage 2 & 3: Select by maximum score, priority tie‑break

if ($candidates.Count -eq 0) {
    $selectedId = $routing.meta.fallbackId
} else {
    $maxScore = ($candidates.Score | Measure-Object -Maximum).Maximum
    $topCandidates = $candidates | Where-Object { $_.Score -eq $maxScore }
    $selectedId = $routing.priority | Where-Object { 
        $_ -in ($topCandidates | Select-Object -ExpandProperty Id) 
    } | Select-Object -First 1
}

# Output the selected skill path

$routing.routes.$selectedId.skill

```

Invoke the router from the command line:

```bash

# Bash interface

./skills/scripts/master-route.sh --hint="android root detection bypass"

# PowerShell interface

.\skills\scripts\master-route.ps1 --hint="frida hook objective-c"

```

---

## Maintaining Coherence with verify-routing-coherence.ps1

Human documentation in [`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md) includes a priority table matching the [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) order. The `skills/scripts/verify-routing-coherence.ps1` script prevents drift between these sources:

```powershell

# Extract priority from routing.json

$jsonPriority = $routing.priority

# Parse MASTER-ROUTING.md table rows

$mdContent = Get-Content "$PSScriptRoot/../MASTER-ROUTING.md" -Raw
$mdPriority = [regex]::Matches($mdContent, '^\|\s*(\d+)\s*\|\s*(R\d+)\s*\|', 'Multiline') | 
    ForEach-Object { $_.Groups[2].Value }

# Compare sequences

if (Compare-Object $jsonPriority $mdPriority) {
    Write-Error "Priority mismatch between routing.json and MASTER-ROUTING.md"
    exit 1
}
Write-Host "Priority list is consistent."

```

Run verification during CI or local development:

```bash
powershell -File skills/scripts/verify-routing-coherence.ps1

```

---

## Summary

- **Keyword matching** evaluates regex rules with `must`, `exclude`, and `mustAll` conditions per route
- **Scoring** counts total matching rules; highest score becomes primary candidate
- **Priority array** deterministically breaks ties by selecting the earliest‑listed route
- **Fallback routing** to `R0` occurs when no keywords match
- **Coherence verification** ensures documentation and configuration remain synchronized

---

## Frequently Asked Questions

### What happens when two routes have identical keyword scores?

The engine consults the `priority` array in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json). The route appearing **earlier** in this ordered list receives precedence. This design allows maintainers to prioritize more specialized skills over general ones without modifying keyword complexity.

### How does the exclude pattern prevent false positives?

The `exclude` field contains a regex that must **not** match for the rule to succeed. For example, an Android route can exclude `\bios\b` to prevent iOS‑related requests from incorrectly matching Android patterns when both platforms share terminology.

### Can I test routing behavior without executing actual skills?

Yes. The repository includes [`skills/scripts/test-routing.sh`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/scripts/test-routing.sh) and `test-routing.ps1` for automated regression testing. These scripts feed known hints through the router and assert expected skill selections, validating that priority order and keyword logic remain correct after configuration changes.