How the Routing Priority Array in routing.json Determines Skill Selection in reverse-skill

The priority array in routing.json serves as a deterministic tie-breaker: after scoring all keyword matches, the router selects the first route from the priority list that appears among the highest-scoring candidates.

The reverse-skill repository implements a two-stage routing system where multiple skills can match the same user prompt. When keyword overlaps occur, the priority array guarantees consistent and predictable skill selection without arbitrary randomness. This mechanism is central to how the platform routes requests to the appropriate skill handler.

The Two-Stage Routing Pipeline

The routing logic operates in distinct phases, each defined in skills/config/routing.json. Understanding both stages clarifies why the priority array matters.

Stage 1: Keyword Matching and Scoring

Every incoming request is evaluated against all routes defined in the routes section of routing.json. Each route contains a keywords list with must patterns and optional exclude patterns.

The scoring rules are documented in the meta section (lines 5–7):

{
  "meta": {
    "scoringRule": "count_of_satisfied_keyword_rules",
    "fallbackId": "R0",
    "description": "Route priority: lower index = higher priority"
  }
}

For each route, the router increments the score by 1 for every keyword rule whose must pattern matches and whose exclude pattern (if present) does not match. Routes with zero matches are discarded.

Stage 2: Priority Resolution for Ties

When multiple routes achieve the same highest score, the priority array (lines 16–21) breaks the tie:

{
  "priority": ["R1", "R3", "R2", "R5", "R4", "R6", "R7", "R8", "R9", "R0"]
}

The router traverses this array left-to-right and selects the first route ID that exists in the candidate set. Leftmost position indicates highest precedence.

Implementation Details from the Source Code

Core Selection Logic

The routing scripts implement this pipeline in Python. The scoring and priority resolution work as follows:

import json
import re

def select_skill(prompt):
    with open('skills/config/routing.json') as f:
        routing = json.load(f)

    candidates = {}
    
    # Stage 1: Keyword matching → compute scores

    for rid, route in routing['routes'].items():
        score = 0
        for kw in route['keywords']:
            if re.search(kw['must'], prompt):
                if 'exclude' not in kw or not re.search(kw['exclude'], prompt):
                    score += 1
        if score:
            candidates[rid] = score

    if not candidates:
        return routing['meta']['fallbackId']  # → "R0"

    # Identify highest-scoring candidates

    max_score = max(candidates.values())
    highest = [rid for rid, s in candidates.items() if s == max_score]

    # Stage 2: Apply priority ordering

    for rid in routing['priority']:
        if rid in highest:
            return rid  # selected route ID

    return routing['meta']['fallbackId']  # defensive fallback

Entry Point Scripts

The platform invokes routing through wrapper scripts. In skills/scripts/master-route.ps1 (Windows) or master-route.sh (Linux/macOS):

$hint = "<user prompt>"
$selectedId = & python -c "import select; print(select.select_skill('$hint'))"

Write-Host "Routing selected: $selectedId"

# Subsequent logic loads the corresponding SKILL.md using the route's 'skill' field

The select_skill() function encapsulates the score → priority → fallback pipeline that determines which skill content gets retrieved.

Routing Priority Array: Design Intent

The priority array in routing.json serves three critical purposes:

  • Determinism — Same input always produces same output, regardless of JSON key ordering or hash randomization
  • Explicit precedence — Route priority is human-readable and version-controlled
  • Conflict resolution — Overlapping keyword patterns are resolved through intentional ordering rather than implementation-dependent behavior

A validation script skills/scripts/verify-routing-coherence.ps1 ensures the priority array remains synchronized with skills/MASTER-ROUTING.md, preventing documentation drift.

Example Scenario: Multiple Keyword Matches

Consider two routes:

Route ID Keywords Matched Score
R3 "api", "design" 2
R5 "api", "design" 2

Both routes match equally. With priority: ["R1", "R3", "R2", "R5", ...], the router selects R3 because it appears before R5 in the array.

If the priority array were ["R1", "R5", "R3", "R2", ...], the selection would be R5 instead.

Summary

  • The priority array in routing.json provides deterministic tie-breaking when multiple routes achieve identical keyword match scores
  • Route selection follows a strict score → priority → fallback pipeline implemented in skills/scripts/master-route.ps1 and master-route.sh
  • Array position determines precedence: leftmost routes win ties against rightmost routes
  • The fallbackId ("R0") catches cases where no keywords match or unexpected errors occur
  • Coherence between priority array and documentation is enforced by verify-routing-coherence.ps1

Frequently Asked Questions

What happens if no routes match any keywords?

The router returns the fallbackId defined in routing.json's meta section, which defaults to "R0". This route typically contains a generic skill handler or error response.

Can the priority array contain routes that don't exist in the routes section?

While technically possible in JSON, the verify-routing-coherence.ps1 script validates consistency between all routing definitions. Missing routes in the priority array would cause validation failures in the CI pipeline.

How does scoring handle partial keyword matches?

Each satisfied keyword rule contributes exactly 1 point to a route's score. The router uses simple counting rather than weighted scoring, making the priority array's role as tie-breaker more significant for complex routing scenarios.

Where should I modify routing behavior for a new skill?

Add your route to skills/config/routing.json in the routes section, then insert your route ID into the priority array at your desired precedence position. Update skills/MASTER-ROUTING.md to document the change, and run verify-routing-coherence.ps1 before committing.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →