# How Priority Ordering Works in reverse-skill routing.json: A Complete Guide

> Understand priority ordering in reverse-skill routing. Learn how keyword matches and the priority array tie-break routes for optimal selection in this comprehensive guide.

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

---

**Priority ordering in `reverse-skill` works as a two-step tie-breaker system: first scoring routes by keyword matches, then using the `priority` array to select the PRIMARY route when multiple routes have equal hit counts.**

The `reverse-skill` project (available at `zhaoxuya520/reverse-skill`) implements a deterministic routing mechanism that decides which reverse-engineering skill executes first based on user hints. The entire logic lives in [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json), where authors control precedence through an explicit, ordered list of route IDs.

## Understanding the Two-Step Routing Algorithm

### Step 1: Keyword Scoring Builds the Candidate Set

Every route (`R1` through `R40`) contains **keyword rules** with `must` patterns. When a user hint matches any pattern, that route receives one hit. After evaluating all routes, the system creates a **candidate set** containing only routes with at least one hit.

The scoring defaults to +1 per matched rule, though individual rules can specify custom scores. The `meta.scoring` section in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) (lines 4-7) documents this behavior and defines the fallback mechanism.

### Step 2: Priority Array Resolves Ties

When multiple routes share the **highest hit count**, the router consults the **`priority` array** (lines 308-313) to break the tie. This array lists route IDs from highest to lowest precedence. The first ID in the array that also appears in the candidate set becomes the **PRIMARY** route.

This design gives authors precise, deterministic control over routing decisions without complex scoring mathematics.

## The Priority Array: Author-Controlled Precedence

The `priority` array in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json) explicitly orders 41 route IDs:

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

```

- **Position 0-9**: Core reverse-engineering skills (APK analysis, binary diff, firmware extraction)
- **Position 10-29**: Specialized tools and frameworks
- **Position 30-40**: Fallback and auxiliary routes, with `R0` as the ultimate generic fallback

Changing the order of IDs directly changes routing outcomes for ambiguous hints. The `verify-routing-coherence.ps1` script enforces consistency between this array and the human-readable table in [`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md) (lines 52-96).

## How the Fallback Mechanism Works

If no route receives any keyword hit, the router uses `meta.fallbackId` (line 5):

```json
{
  "meta": {
    "fallbackId": "R0",
    "scoring": "Summation of matched keyword scores; priority tie-breaker"
  }
}

```

`R0` represents the generic reverse-engineering skill. The system also suggests opening [`routing.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.md) for manual review when this occurs.

## Running the Router: Code Examples

### Execute the Official Router Script

```powershell
powershell -File skills/scripts/master-route.ps1 -Hint "analyze Android APK with Frida"

```

This script implements the algorithm exactly as defined in [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json).

### Simplified Algorithm Implementation

```powershell

# Load routing configuration

$routes     = Get-Content skills/config/routing.json | ConvertFrom-Json
$candidates = @()

# Phase 1: Score all routes by keyword matches

foreach ($id in $routes.routes.Keys) {
    foreach ($kw in $routes.routes[$id].keywords) {
        $matchesMust    = $Hint -match $kw.must
        $passesExclude  = !($kw.exclude) -or ($Hint -notmatch $kw.exclude)
        
        if ($matchesMust -and $passesExclude) {
            $candidates += $id
            break   # One hit per route sufficient for basic scoring

        }
    }
}

# Phase 2: Resolve PRIMARY via priority ordering

if ($candidates.Count -eq 0) {
    $primary = $routes.meta.fallbackId   # "R0"

} else {
    foreach ($p in $routes.priority) {
        if ($candidates -contains $p) {
            $primary = $p
            break   # First match in priority array wins

        }
    }
}

Write-Host "PRIMARY route: $primary"

```

### Real Routing Example

Consider this hint:

```

"reverse engineer iOS app, need to bypass jailbreak detection using Frida"

```

1. **Scoring phase**:
   - `R4` (iOS reverse) hits on `ios`/`appstore` patterns → **1 hit**
   - `R21` (Frida scripting) hits on `frida` pattern → **1 hit**
   - `R0` (generic) may hit on `reverse engineer` → **1 hit**

2. **Tie-break phase**: All three have equal scores. The `priority` array shows `R4` at position 0, `R21` at position 10, `R0` at position 40.

3. **Result**: **PRIMARY = R4** (iOS reverse) due to priority ordering precedence.

## Key Files Defining Priority Ordering

| File | Role | Critical Lines |
|------|------|--------------|
| [`skills/config/routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/config/routing.json) | Source of truth for priority array and scoring rules | 1-313 |
| [`skills/MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/skills/MASTER-ROUTING.md) | Human-readable priority table synchronized with JSON | 52-96 |
| `skills/scripts/master-route.ps1` | Production implementation of the routing algorithm | Full file |
| `skills/scripts/verify-routing-coherence.ps1` | CI validation ensuring array/table consistency | Full file |

## Summary

- **Priority ordering** resolves routing ties deterministically using author-controlled sequence
- **Two-step process**: keyword scoring creates candidates, priority array selects winner
- **`priority` array** position determines precedence—earlier IDs win ties
- **`fallbackId: "R0"`** catches unmatched hints with generic skill
- **Consistency enforced** by `verify-routing-coherence.ps1` between JSON and Markdown documentation

## Frequently Asked Questions

### What happens if two routes have different scores but the lower-priority one scores higher?

The route with the **higher score always wins**, regardless of priority ordering. The `priority` array only activates when multiple routes share the identical highest hit count. Score takes absolute precedence over position in the priority list.

### Can I modify the priority ordering without changing routing behavior for unambiguous hints?

Yes. Changing the `priority` array only affects **tie-break situations** where multiple routes receive equal top scores. Hints with a single clear winner or distinctly dominant scores route identically regardless of priority adjustments.

### How does the system prevent priority drift between code and documentation?

The `skills/scripts/verify-routing-coherence.ps1` script runs in CI to validate that [`routing.json`](https://github.com/zhaoxuya520/reverse-skill/blob/main/routing.json)'s `priority` array matches the sequence defined in [`MASTER-ROUTING.md`](https://github.com/zhaoxuya520/reverse-skill/blob/main/MASTER-ROUTING.md). Any divergence fails the build, ensuring the human-readable table always reflects actual runtime behavior.

### Why does R0 appear last in the priority array rather than first?

`R0` serves as the **generic fallback** for unmatched hints via `fallbackId`, not through priority ordering. Placing it last ensures that if it accidentally hits keywords simultaneously with specialized routes, those specific skills win the tie. This prevents over-generalization when precise tools are available.